From eaf9b562fa0041449fea7608bb55498b07b45c87 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 3 Nov 2010 19:08:46 +0300 Subject: [PATCH 001/257] duplicate lines action (IDEA-56385) --- .../editor/actions/DuplicateAction.java | 45 ++++++++-------- .../editor/actions/DuplicateLinesAction.java | 51 +++++++++++++++++++ .../openapi/editor/ex/util/EditorUtil.java | 13 +++-- .../src/idea/Keymap_Eclipse.xml | 3 +- .../src/idea/PlatformActions.xml | 1 + 5 files changed, 86 insertions(+), 27 deletions(-) create mode 100644 platform/platform-impl/src/com/intellij/openapi/editor/actions/DuplicateLinesAction.java 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 34dc39f1b531..50749c166843 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 @@ -62,29 +62,34 @@ public class DuplicateAction extends EditorAction { editor.getSelectionModel().setSelection(end, end+s.length()); } else { - Pair lines = EditorUtil.calcCaretLinesRange(editor); - int offset = caretModel.getOffset(); - - LogicalPosition lineStart = lines.first; - LogicalPosition nextLineStart = lines.second; - int start = editor.logicalPositionToOffset(lineStart); - int end = editor.logicalPositionToOffset(nextLineStart); - String s = document.getCharsSequence().subSequence(start, end).toString(); - final int lineToCheck = nextLineStart.line - 1; - - int newOffset = end + offset - start; - if(lineToCheck == document.getLineCount () /*empty document*/ || - document.getLineSeparatorLength(lineToCheck) == 0) { - s = "\n"+s; - newOffset++; - } - document.insertString(end, s); - - caretModel.moveToOffset(newOffset); - scrollingModel.scrollToCaret(ScrollType.RELATIVE); + duplicateLinesRange(editor, document, caretModel.getVisualPosition(), caretModel.getVisualPosition()); } } + static Pair duplicateLinesRange(Editor editor, Document document, VisualPosition rangeStart, VisualPosition rangeEnd) { + Pair lines = EditorUtil.calcCaretLinesRange(editor, rangeStart, rangeEnd); + int offset = editor.getCaretModel().getOffset(); + + LogicalPosition lineStart = lines.first; + LogicalPosition nextLineStart = lines.second; + int start = editor.logicalPositionToOffset(lineStart); + int end = editor.logicalPositionToOffset(nextLineStart); + String s = document.getCharsSequence().subSequence(start, end).toString(); + final int lineToCheck = nextLineStart.line - 1; + + int newOffset = end + offset - start; + if(lineToCheck == document.getLineCount () /*empty document*/ || + document.getLineSeparatorLength(lineToCheck) == 0) { + s = "\n"+s; + newOffset++; + } + document.insertString(end, s); + + editor.getCaretModel().moveToOffset(newOffset); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + return new Pair(end, end+s.length()); + } + @Override public void update(final Editor editor, final Presentation presentation, final DataContext dataContext) { super.update(editor, presentation, dataContext); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/DuplicateLinesAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/DuplicateLinesAction.java new file mode 100644 index 000000000000..fc3c86c50aed --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/DuplicateLinesAction.java @@ -0,0 +1,51 @@ +/* + * Copyright 2000-2010 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.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.VisualPosition; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; +import com.intellij.openapi.util.Pair; + +/** + * @author yole + */ +public class DuplicateLinesAction extends EditorAction { + public DuplicateLinesAction() { + super(new Handler()); + } + + private static class Handler extends EditorWriteActionHandler { + @Override + public void executeWriteAction(Editor editor, DataContext dataContext) { + if (editor.getSelectionModel().hasSelection()) { + int selStart = editor.getSelectionModel().getSelectionStart(); + int selEnd = editor.getSelectionModel().getSelectionEnd(); + VisualPosition rangeStart = editor.offsetToVisualPosition(Math.min(selStart, selEnd)); + VisualPosition rangeEnd = editor.offsetToVisualPosition(Math.max(selStart, selEnd)); + final Pair copiedRange = + DuplicateAction.duplicateLinesRange(editor, editor.getDocument(), rangeStart, rangeEnd); + editor.getSelectionModel().setSelection(copiedRange.first, copiedRange.second); + } + else { + VisualPosition caretPos = editor.getCaretModel().getVisualPosition(); + DuplicateAction.duplicateLinesRange(editor, editor.getDocument(), caretPos, caretPos); + } + } + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java index bc5b87810c7a..4db50963e5b8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java @@ -544,23 +544,26 @@ public class EditorUtil { return result; } + public static Pair calcCaretLinesRange(Editor editor) { + return calcCaretLinesRange(editor, editor.getCaretModel().getVisualPosition(), editor.getCaretModel().getVisualPosition()); + } + /** * Calculates the closest non-soft-wrapped logical positions for current caret position. * * @param editor target editor to use * @return pair of non-soft-wrapped logical positions closest to the caret position of the given editor */ - public static Pair calcCaretLinesRange(Editor editor) { - VisualPosition caret = editor.getCaretModel().getVisualPosition(); - int visualLine = caret.line; + public static Pair calcCaretLinesRange(Editor editor, VisualPosition start, VisualPosition end) { + int visualLine = start.line; LogicalPosition lineStart = editor.visualToLogicalPosition(new VisualPosition(visualLine, 0)); while (lineStart.softWrapLinesOnCurrentLogicalLine > 0) { lineStart = editor.visualToLogicalPosition(new VisualPosition(--visualLine, 0)); } - visualLine = caret.line + 1; - LogicalPosition nextLineStart = editor.visualToLogicalPosition(new VisualPosition(caret.line + 1, 0)); + visualLine = end.line + 1; + LogicalPosition nextLineStart = editor.visualToLogicalPosition(new VisualPosition(end.line + 1, 0)); while (nextLineStart.line == lineStart.line) { nextLineStart = editor.visualToLogicalPosition(new VisualPosition(++visualLine, 0)); } diff --git a/platform/platform-resources/src/idea/Keymap_Eclipse.xml b/platform/platform-resources/src/idea/Keymap_Eclipse.xml index 838b49947ae1..7198e1f92409 100644 --- a/platform/platform-resources/src/idea/Keymap_Eclipse.xml +++ b/platform/platform-resources/src/idea/Keymap_Eclipse.xml @@ -65,8 +65,7 @@ - - + diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index 2f90dfb46abd..55c40538ce57 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -71,6 +71,7 @@ + From c4e12776d58e050bbba54849aaceeec2444011cd Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 3 Nov 2010 19:24:03 +0300 Subject: [PATCH 002/257] unchecking "Confirm window to open project in" works (IDEA-60332); some refactoring --- java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java | 2 +- .../platform-api/src/com/intellij/ide/GeneralSettings.java | 4 ++++ .../src/com/intellij/ide/GeneralSettingsConfigurable.java | 5 ++++- .../platform-impl/src/com/intellij/ide/impl/ProjectUtil.java | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java b/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java index d6fc7c720a39..38821aa31838 100644 --- a/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java +++ b/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java @@ -191,7 +191,7 @@ public class NewProjectUtil { if (openProjects.length > 0) { final GeneralSettings settings = GeneralSettings.getInstance(); int exitCode = settings.getConfirmOpenNewProject(); - if (exitCode < 0) { + if (exitCode == GeneralSettings.OPEN_PROJECT_ASK) { exitCode = Messages.showDialog(IdeBundle.message("prompt.open.project.in.new.frame"), IdeBundle.message("title.new.project"), new String[]{IdeBundle.message("button.newframe"), IdeBundle.message("button.existingframe")}, 1, 0, Messages.getQuestionIcon(), new ProjectNewWindowDoNotAskOption()); diff --git a/platform/platform-api/src/com/intellij/ide/GeneralSettings.java b/platform/platform-api/src/com/intellij/ide/GeneralSettings.java index 9e42c449a645..142faa3a4637 100644 --- a/platform/platform-api/src/com/intellij/ide/GeneralSettings.java +++ b/platform/platform-api/src/com/intellij/ide/GeneralSettings.java @@ -490,6 +490,10 @@ public class GeneralSettings implements NamedJDOMExternalizable, ExportableAppli myConfirmOpenNewProject = confirmOpenNewProject; } + public static final int OPEN_PROJECT_ASK = -1; + public static final int OPEN_PROJECT_NEW_WINDOW = 0; + public static final int OPEN_PROJECT_SAME_WINDOW = 1; + public boolean isSearchInBackground() { return mySearchInBackground; } diff --git a/platform/platform-impl/src/com/intellij/ide/GeneralSettingsConfigurable.java b/platform/platform-impl/src/com/intellij/ide/GeneralSettingsConfigurable.java index baf6dab0a496..e11111b063b8 100644 --- a/platform/platform-impl/src/com/intellij/ide/GeneralSettingsConfigurable.java +++ b/platform/platform-impl/src/com/intellij/ide/GeneralSettingsConfigurable.java @@ -51,7 +51,10 @@ public class GeneralSettingsConfigurable extends CompositeConfigurable Date: Wed, 3 Nov 2010 20:11:46 +0300 Subject: [PATCH 003/257] remember statistics splitter proportion in test output (part of IDEA-25446) --- .../testframework/ui/TestResultsPanel.java | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/platform/testRunner/src/com/intellij/execution/testframework/ui/TestResultsPanel.java b/platform/testRunner/src/com/intellij/execution/testframework/ui/TestResultsPanel.java index 49bda12626d5..c904dee8271f 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/ui/TestResultsPanel.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/ui/TestResultsPanel.java @@ -42,10 +42,11 @@ import java.beans.PropertyChangeListener; public abstract class TestResultsPanel extends JPanel implements Disposable { private JScrollPane myLeftPane; private JComponent myStatisticsComponent; - private Splitter mySplitter; + private Splitter myStatisticsSplitter; protected final JComponent myConsole; protected ToolbarPanel myToolbarPanel; private final String mySplitterProportionProperty; + private final String myStatisticsSplitterProportionProperty; private final float mySplitterDefaultProportion; protected final RunnerSettings myRunnerSettings; protected final ConfigurationPerRunnerSettings myConfigurationSettings; @@ -62,6 +63,7 @@ public abstract class TestResultsPanel extends JPanel implements Disposable { myProperties = properties; mySplitterProportionProperty = splitterProportionProperty; mySplitterDefaultProportion = splitterDefaultProportion; + myStatisticsSplitterProportionProperty = mySplitterProportionProperty + "_Statistics"; myRunnerSettings = runnerSettings; myConfigurationSettings = configurationSettings; } @@ -89,7 +91,7 @@ public abstract class TestResultsPanel extends JPanel implements Disposable { myStatusLine.setMinimumSize(new Dimension(0, myStatusLine.getMinimumSize().height)); final JPanel rightPanel = new JPanel(new BorderLayout()); rightPanel.add(SameHeightPanel.wrap(myStatusLine, myToolbarPanel), BorderLayout.NORTH); - mySplitter = new Splitter(); + myStatisticsSplitter = createSplitter(myStatisticsSplitterProportionProperty, 0.5f); new AwtVisitor(myConsole) { public boolean visit(Component component) { if (component instanceof JScrollPane) { @@ -99,25 +101,29 @@ public abstract class TestResultsPanel extends JPanel implements Disposable { return false; } }; - mySplitter.setFirstComponent(createOutputTab(myConsole, myConsoleActions)); + myStatisticsSplitter.setFirstComponent(createOutputTab(myConsole, myConsoleActions)); if (TestConsoleProperties.SHOW_STATISTICS.value(myProperties)) { - mySplitter.setSecondComponent(myStatisticsComponent); + showStatistics(); } myProperties.addListener(TestConsoleProperties.SHOW_STATISTICS, new TestFrameworkPropertyListener() { public void onChanged(Boolean value) { if (value.booleanValue()) { - mySplitter.setSecondComponent(myStatisticsComponent); + showStatistics(); } else { - mySplitter.setSecondComponent(null); + myStatisticsSplitter.setSecondComponent(null); } } }); - rightPanel.add(mySplitter, BorderLayout.CENTER); + rightPanel.add(myStatisticsSplitter, BorderLayout.CENTER); splitter.setSecondComponent(rightPanel); setLeftComponent(testTreeView); } + private void showStatistics() { + myStatisticsSplitter.setSecondComponent(myStatisticsComponent); + } + protected abstract JComponent createStatisticsPanel(); protected ToolbarPanel createToolbarPanel() { From 0ea93b779ea953afac30dfa1dbf15ce765642072 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 3 Nov 2010 21:03:08 +0300 Subject: [PATCH 004/257] use message bus for directory mapping change notifications --- .../openapi/vcs/ProjectLevelVcsManager.java | 5 ++++ .../vcs/impl/ProjectLevelVcsManagerImpl.java | 24 +++++++++++++------ .../vcs/impl/projectlevelman/NewMappings.java | 9 +++---- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/ProjectLevelVcsManager.java b/platform/vcs-api/src/com/intellij/openapi/vcs/ProjectLevelVcsManager.java index 8b0324c4af22..f85e747459de 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/ProjectLevelVcsManager.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/ProjectLevelVcsManager.java @@ -26,6 +26,7 @@ import com.intellij.openapi.vcs.impl.VcsDescriptor; import com.intellij.openapi.vcs.update.UpdatedFiles; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Processor; +import com.intellij.util.messages.Topic; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -208,6 +209,7 @@ public abstract class ProjectLevelVcsManager { * Adds a listener for receiving notifications about changes in VCS configuration for the project. * * @param listener the listener instance. + * @deprecated use {@link #VCS_CONFIGURATION_CHANGED} instead * @since 6.0 */ public abstract void addVcsListener(VcsListener listener); @@ -216,6 +218,7 @@ public abstract class ProjectLevelVcsManager { * Removes a listener for receiving notifications about changes in VCS configuration for the project. * * @param listener the listener instance. + * @deprecated use {@link #VCS_CONFIGURATION_CHANGED} instead * @since 6.0 */ public abstract void removeVcsListener(VcsListener listener); @@ -270,4 +273,6 @@ public abstract class ProjectLevelVcsManager { public abstract AbstractVcs findVersioningVcs(VirtualFile file); public abstract CheckoutProvider.Listener getCompositeCheckoutListener(); + + public static Topic VCS_CONFIGURATION_CHANGED = Topic.create("VCS configuration changed", VcsListener.class); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java index 87c51cd38bd6..ee3866ea4bd3 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java @@ -57,6 +57,8 @@ import com.intellij.util.EventDispatcher; import com.intellij.util.Icons; import com.intellij.util.Processor; import com.intellij.util.containers.Convertor; +import com.intellij.util.messages.MessageBus; +import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.ui.EditorAdapter; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -76,6 +78,7 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme private final NewMappings myMappings; private final Project myProject; + private final MessageBus myMessageBus; private final MappingsToRoots myMappingsToRoots; private ContentManager myContentManager; @@ -91,8 +94,7 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme @NonNls private static final String ATTRIBUTE_CLASS = "class"; private final List myRegisteredBeforeCheckinHandlers = new ArrayList(); - private final EventDispatcher myEventDispatcher = EventDispatcher.create(VcsListener.class); - + private boolean myMappingsLoaded = false; private boolean myHaveLegacyVcsConfiguration = false; private boolean myCheckinHandlerFactoriesLoaded = false; @@ -104,8 +106,9 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme private final List> myPendingOutput = new ArrayList>(); - public ProjectLevelVcsManagerImpl(Project project, final FileStatusManager manager) { + public ProjectLevelVcsManagerImpl(Project project, final FileStatusManager manager, MessageBus messageBus) { myProject = project; + myMessageBus = messageBus; mySerialization = new ProjectLevelVcsManagerSerialization(); myOptionsAndConfirmations = new OptionsAndConfirmations(); @@ -113,7 +116,7 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme myBackgroundableActionHandlerMap = new HashMap(); myInitialization = new VcsInitialization(myProject); - myMappings = new NewMappings(myProject, myEventDispatcher, this, manager); + myMappings = new NewMappings(myProject, myMessageBus, this, manager); myMappingsToRoots = new MappingsToRoots(myMappings, myProject); } @@ -503,12 +506,19 @@ public void addMessageToConsoleWindow(final String message, final TextAttributes myRegisteredBeforeCheckinHandlers.remove(handler); } + private final Map myAdapters = new HashMap(); + public void addVcsListener(VcsListener listener) { - myEventDispatcher.addListener(listener); + final MessageBusConnection connection = myMessageBus.connect(); + connection.subscribe(VCS_CONFIGURATION_CHANGED, listener); + myAdapters.put(listener, connection); } public void removeVcsListener(VcsListener listener) { - myEventDispatcher.removeListener(listener); + final MessageBusConnection connection = myAdapters.remove(listener); + if (connection != null) { + connection.disconnect(); + } } public void startBackgroundVcsOperation() { @@ -557,7 +567,7 @@ public void addMessageToConsoleWindow(final String message, final TextAttributes } public void notifyDirectoryMappingChanged() { - myEventDispatcher.getMulticaster().directoryMappingChanged(); + myMessageBus.syncPublisher(VCS_CONFIGURATION_CHANGED).directoryMappingChanged(); } public void readDirectoryMappings(final Element element) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java index ad7c13d705e6..921fcf1673e6 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java @@ -34,6 +34,7 @@ import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.EventDispatcher; import com.intellij.util.containers.Convertor; +import com.intellij.util.messages.MessageBus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -50,22 +51,22 @@ public class NewMappings { private FileWatchRequestsManager myFileWatchRequestsManager; private final DefaultVcsRootPolicy myDefaultVcsRootPolicy; - private final EventDispatcher myEventDispatcher; + private final MessageBus myMessageBus; private final FileStatusManager myFileStatusManager; private final Project myProject; private boolean myActivated; - public NewMappings(final Project project, final EventDispatcher eventDispatcher, + public NewMappings(final Project project, final MessageBus messageBus, final ProjectLevelVcsManagerImpl vcsManager, FileStatusManager fileStatusManager) { myProject = project; + myMessageBus = messageBus; myFileStatusManager = fileStatusManager; myLock = new Object(); myVcsToPaths = new HashMap>(); myFileWatchRequestsManager = new FileWatchRequestsManager(myProject, this, LocalFileSystem.getInstance()); myDefaultVcsRootPolicy = DefaultVcsRootPolicy.getInstance(project); myActiveVcses = new AbstractVcs[0]; - myEventDispatcher = eventDispatcher; final ArrayList listStr = new ArrayList(); final VcsDirectoryMapping mapping = new VcsDirectoryMapping("", ""); @@ -175,7 +176,7 @@ public class NewMappings { } public void mappingsChanged() { - myEventDispatcher.getMulticaster().directoryMappingChanged(); + myMessageBus.syncPublisher(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED).directoryMappingChanged(); myFileStatusManager.fileStatusesChanged(); myFileWatchRequestsManager.ping(); } From fb2c0874a5f3de662da43a178537b39c6b461f89 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 3 Nov 2010 21:18:45 +0300 Subject: [PATCH 005/257] always show tooltip for incoming changes indicator; hide indicator if VCS doesn't support committed changes cache (IDEA-56298) --- .../committed/IncomingChangesIndicator.java | 65 +++++++++++-------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/IncomingChangesIndicator.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/IncomingChangesIndicator.java index 2d3f63e5c0b5..fb42df5b4dc4 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/IncomingChangesIndicator.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/IncomingChangesIndicator.java @@ -16,21 +16,22 @@ package com.intellij.openapi.vcs.changes.committed; import com.intellij.ide.DataManager; -import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.ProjectComponent; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vcs.AbstractVcs; +import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.VcsBundle; +import com.intellij.openapi.vcs.VcsListener; import com.intellij.openapi.vcs.changes.ui.ChangesViewContentManager; import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList; import com.intellij.openapi.wm.*; import com.intellij.util.Consumer; import com.intellij.util.messages.MessageBus; +import com.intellij.util.messages.MessageBusConnection; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -43,7 +44,7 @@ import java.util.List; /** * @author yole */ -public class IncomingChangesIndicator implements ProjectComponent { +public class IncomingChangesIndicator { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.committed.IncomingChangesIndicator"); private final Project myProject; @@ -53,7 +54,8 @@ public class IncomingChangesIndicator implements ProjectComponent { public IncomingChangesIndicator(Project project, CommittedChangesCache cache, MessageBus bus) { myProject = project; myCache = cache; - bus.connect().subscribe(CommittedChangesCache.COMMITTED_TOPIC, new CommittedChangesAdapter() { + final MessageBusConnection connection = bus.connect(); + connection.subscribe(CommittedChangesCache.COMMITTED_TOPIC, new CommittedChangesAdapter() { public void incomingChangesUpdated(@Nullable final List receivedChanges) { ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { @@ -62,36 +64,45 @@ public class IncomingChangesIndicator implements ProjectComponent { }); } }); - } - - public void projectOpened() { - final StatusBar statusBar = WindowManager.getInstance().getStatusBar(myProject); - myIndicatorComponent = new IndicatorComponent(); - - statusBar.addWidget(myIndicatorComponent); - Disposer.register(myProject, new Disposable() { - public void dispose() { - statusBar.removeWidget(myIndicatorComponent.ID()); + connection.subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, new VcsListener() { + @Override + public void directoryMappingChanged() { + updateIndicatorVisibility(); } }); } - public void projectClosed() { + private void updateIndicatorVisibility() { + final StatusBar statusBar = WindowManager.getInstance().getStatusBar(myProject); + if (needIndicator()) { + if (myIndicatorComponent == null) { + myIndicatorComponent = new IndicatorComponent(); + statusBar.addWidget(myIndicatorComponent, myProject); + refreshIndicator(); + } + } + else { + if (myIndicatorComponent != null) { + statusBar.removeWidget(myIndicatorComponent.ID()); + myIndicatorComponent = null; + } + } } - @NonNls - @NotNull - public String getComponentName() { - return "IncomingChangesIndicator"; - } - - public void initComponent() { - } - - public void disposeComponent() { + private boolean needIndicator() { + final AbstractVcs[] vcss = ProjectLevelVcsManager.getInstance(myProject).getAllActiveVcss(); + for (AbstractVcs vcs : vcss) { + if (vcs.getCachingCommittedChangesProvider() != null) { + return true; + } + } + return false; } private void refreshIndicator() { + if (myIndicatorComponent == null) { + return; + } final List list = myCache.getCachedIncomingChanges(); if (list == null || list.isEmpty()) { debug("Refreshing indicator: no changes"); @@ -120,7 +131,7 @@ public class IncomingChangesIndicator implements ProjectComponent { } void clear() { - update(CHANGES_NOT_AVAILABLE_ICON, null); + update(CHANGES_NOT_AVAILABLE_ICON, "No incoming changelists available"); } void setChangesAvailable(@NotNull final String toolTipText) { From 56428876e4369738522e33faa5ffd46f5f9a1ccb Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 8 Nov 2010 15:25:27 +0300 Subject: [PATCH 006/257] HighPriorityAction (IDEA-19522) --- .../daemon/impl/analysis/InsertRequiredAttributeFix.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/InsertRequiredAttributeFix.java b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/InsertRequiredAttributeFix.java index 356467eb2747..2111ab3a5756 100644 --- a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/InsertRequiredAttributeFix.java +++ b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/InsertRequiredAttributeFix.java @@ -17,6 +17,7 @@ package com.intellij.codeInsight.daemon.impl.analysis; import com.intellij.codeInsight.CodeInsightUtilBase; import com.intellij.codeInsight.daemon.XmlErrorMessages; +import com.intellij.codeInsight.intention.HighPriorityAction; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; @@ -44,7 +45,7 @@ import org.jetbrains.annotations.NotNull; * User: anna * Date: 18-Nov-2005 */ -public class InsertRequiredAttributeFix implements IntentionAction, LocalQuickFix { +public class InsertRequiredAttributeFix implements IntentionAction, LocalQuickFix, HighPriorityAction { private final XmlTag myTag; private final String myAttrName; private final String[] myValues; From a7462483ceb6e1a9d764d8ab805f97bffff62c9f Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 8 Nov 2010 16:20:59 +0300 Subject: [PATCH 007/257] diagnostics for IDEA-56484 --- .../src/com/intellij/refactoring/rename/RenameUtil.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameUtil.java b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameUtil.java index 988b13bdd795..9d18e8486329 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameUtil.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameUtil.java @@ -66,6 +66,10 @@ public class RenameUtil { Collection refs = processor.findReferences(element); for (PsiReference ref : refs) { + if (ref == null) { + LOG.error("null reference from processor " + processor); + continue; + } PsiElement referenceElement = ref.getElement(); result.add(new MoveRenameUsageInfo(referenceElement, ref, ref.getRangeInElement().getStartOffset(), ref.getRangeInElement().getEndOffset(), element, From 9eac765bcdaadb8da36eccb4c5b5d1e3a918790d Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Mon, 8 Nov 2010 18:48:24 +0300 Subject: [PATCH 008/257] Test for #IDEA-60927 --- .../refactoring/rename/RenameTest.groovy | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/rename/RenameTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/rename/RenameTest.groovy index a921fe515d4e..c758b8d07696 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/rename/RenameTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/rename/RenameTest.groovy @@ -186,7 +186,31 @@ class A { }""" } - + public void _testRenameFieldWithNonstandardName() { + def file = myFixture.configureByText("a.groovy", """ +class SomeBean { + String xXx = "field" + public String getxXx() { + return "method" + } + public static void main(String[] args) { + println(new SomeBean().xXx) + } +} +""") + myFixture.renameElementAtCaret "xXx777" + assertEquals """ +class SomeBean { + String xXx777 = "field" + public String getxXx777() { + return "method" + } + public static void main(String[] args) { + println(new SomeBean().xXx777) + } +} +""", file.text + } public void doTest() throws Throwable { final String testFile = getTestName(true).replace('$', '/') + ".test"; From 8c868505a3f175c2d9267c85c0fb41c476e4c191 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Mon, 8 Nov 2010 19:20:48 +0300 Subject: [PATCH 009/257] navbar location, focus and plainting fixes --- .../ide/navigationToolbar/NavBarPanel.java | 9 ++++---- .../src/com/intellij/ide/IdeEventQueue.java | 22 +++++++++++++++++++ .../wm/impl/ToolWindowManagerImpl.java | 18 +++++++++++---- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java index af4979d6bcfb..bc4b12ebf655 100644 --- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java @@ -103,7 +103,7 @@ public class NavBarPanel extends OpaquePanel.List implements DataProvider, Popup private LightweightHint myHint = null; private ListPopupImpl myNodePopup = null; - private Container myHintContainer; + private JComponent myHintContainer; private Component myContextComponent; private Runnable myRunWhenListRebuilt; @@ -1041,7 +1041,8 @@ public class NavBarPanel extends OpaquePanel.List implements DataProvider, Popup final AsyncResult result = new AsyncResult(); if (myHintContainer != null) { final Point p = AbstractPopup.getCenterOf(myHintContainer, this); - p.y -= myHintContainer.getHeight() / 4; + p.y -= myHintContainer.getVisibleRect().height / 4; + result.setDone(RelativePoint.fromScreen(p)); } else { @@ -1114,8 +1115,8 @@ public class NavBarPanel extends OpaquePanel.List implements DataProvider, Popup boolean selected = myModel.getSelectedIndex() == myIndex; - setPaintFocusBorder(selected); - setFocusBorderAroundIcon(true); + setPaintFocusBorder(!focused && selected); + setFocusBorderAroundIcon(false); setBackground(selected && focused ? UIUtil.getListSelectionBackground() diff --git a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java index b5efa1e0163a..65e04b9340a6 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java +++ b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java @@ -39,6 +39,7 @@ import com.intellij.util.Alarm; import com.intellij.util.ReflectionUtil; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -48,6 +49,7 @@ import java.awt.event.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.*; @@ -569,6 +571,26 @@ public class IdeEventQueue extends EventQueue { if (!mouseEventsAhead) { Window showingWindow = mgr.getActiveWindow(); + if (showingWindow == null) { + Method getNativeFocusOwner = ReflectionUtil.getDeclaredMethod(KeyboardFocusManager.class, "getNativeFocusOwner"); + if (getNativeFocusOwner != null) { + getNativeFocusOwner.setAccessible(true); + try { + Object owner = getNativeFocusOwner.invoke(mgr); + if (owner instanceof Component) { + Component nativeFocusOwner = (Component)owner; + if (nativeFocusOwner instanceof Window) { + showingWindow = (Window)nativeFocusOwner; + } else { + showingWindow = SwingUtilities.getWindowAncestor(nativeFocusOwner); + } + } + } + catch (Exception e1) { + LOG.debug(e1); + } + } + } if (showingWindow != null) { final IdeFocusManager fm = IdeFocusManager.findInstanceByComponent(showingWindow); Runnable requestDefaultFocus = new Runnable() { diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java index 273f62fea55f..adf6866eacf3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java @@ -496,19 +496,29 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } private void activateEditorComponent(final boolean forced) { + activateEditorComponent(forced, false); + } + private void activateEditorComponent(final boolean forced, boolean now) { if (LOG.isDebugEnabled()) { LOG.debug("enter: activateEditorComponent()"); } ApplicationManager.getApplication().assertIsDispatchThread(); - getFocusManager().doWhenFocusSettlesDown(new Runnable() { + Runnable runnable = new Runnable() { @Override public void run() { final ArrayList commandList = new ArrayList(); activateEditorComponentImpl(getSplittersFromFocus(), commandList, forced); execute(commandList); } - }); + }; + + if (now) { + runnable.run(); + } else { + getFocusManager().doWhenFocusSettlesDown(runnable); + + } } private EditorsSplitters getSplittersFromFocus() { @@ -2035,10 +2045,10 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements if (ModalityState.NON_MODAL.equals(ModalityState.current())) { final String activeId = getActiveToolWindowId(); if (myEditorComponentActive || activeId == null || getToolWindow(activeId) == null) { - activateEditorComponent(forced); + activateEditorComponent(forced, true); } else { - activateToolWindow(activeId, forced, false); + activateToolWindow(activeId, forced, true); } } return new ActionCallback.Done(); From fa53d89041ac7eba2b7c1dadf65f61197f63b850 Mon Sep 17 00:00:00 2001 From: "peter.gromov" Date: Mon, 8 Nov 2010 19:16:36 +0300 Subject: [PATCH 010/257] lookup progress which doesn't lead to size jumping --- .../codeInsight/lookup/impl/LookupImpl.java | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 55cdba73dde1..c3d1ec195f9e 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -97,6 +97,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { private boolean myFocused = true; private String myAdditionalPrefix = ""; private final AsyncProcessIcon myProcessIcon = new AsyncProcessIcon("Completion progress"); + private final JPanel myIconPanel = new JPanel(new BorderLayout()); private volatile boolean myCalculating; private final JLabel myAdComponent; private volatile String myAdText; @@ -112,7 +113,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { myProject = project; myEditor = editor; - myProcessIcon.setVisible(false); + myIconPanel.setVisible(false); myCellRenderer = new LookupCellRenderer(this); myList.setCellRenderer(myCellRenderer); @@ -127,14 +128,13 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { getComponent().add(scrollPane, BorderLayout.NORTH); scrollPane.setBorder(null); - JPanel bottomPanel = new JPanel(new BorderLayout()); - - bottomPanel.add(myProcessIcon, BorderLayout.EAST); myAdComponent = HintUtil.createAdComponent(null); - bottomPanel.add(myAdComponent, BorderLayout.CENTER); - getComponent().add(bottomPanel, BorderLayout.SOUTH); + getComponent().add(myAdComponent, BorderLayout.SOUTH); getComponent().setBorder(new BegPopupMenuBorder()); + myIconPanel.setBackground(Color.LIGHT_GRAY); + myIconPanel.add(myProcessIcon); + final ListModel model = myList.getModel(); addEmptyItem((DefaultListModel)model); updateListHeight(model); @@ -164,7 +164,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { public void setCalculating(final boolean calculating) { myCalculating = calculating; - myProcessIcon.setVisible(calculating); + myIconPanel.setVisible(calculating); if (calculating) { myProcessIcon.resume(); } else { @@ -306,11 +306,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { updateListHeight(model); - myAdComponent.setPreferredSize(null); myAdComponent.setText(myAdText); - if (myAdText != null) { - myAdComponent.setPreferredSize(new Dimension(myAdComponent.getPreferredSize().width, myProcessIcon.getPreferredSize().height)); - } if (hasItems) { myList.setFixedCellWidth(Math.max(myLookupTextWidth + myCellRenderer.getIconIndent(), myAdComponent.getPreferredSize().width)); @@ -584,6 +580,8 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { HintManagerImpl hintManager = HintManagerImpl.getInstanceImpl(); hintManager.showEditorHint(this, myEditor, p, HintManagerImpl.HIDE_BY_ESCAPE | HintManagerImpl.UPDATE_BY_SCROLLING, 0, false); + getComponent().getRootPane().getLayeredPane().add(myIconPanel, 42, 0); + myShownStamp = System.currentTimeMillis(); } @@ -976,6 +974,9 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { Point point = calculatePosition(); updateBounds(point.x,point.y); + final Dimension size = myProcessIcon.getPreferredSize(); + myIconPanel.setBounds(getComponent().getRootPane().getLayeredPane().getWidth() - size.width, 0, size.width, size.height); + HintManagerImpl.adjustEditorHintPosition(this, myEditor, point); } } From 487b0edba89ca90a08a14d099eb22dca6622dd38 Mon Sep 17 00:00:00 2001 From: "peter.gromov" Date: Mon, 8 Nov 2010 19:22:50 +0300 Subject: [PATCH 011/257] more interruptibility in class name completion --- .../impl/search/AllClassesSearchExecutor.java | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/search/AllClassesSearchExecutor.java b/java/java-impl/src/com/intellij/psi/impl/search/AllClassesSearchExecutor.java index 817c937cf562..e2fcbcec8acd 100644 --- a/java/java-impl/src/com/intellij/psi/impl/search/AllClassesSearchExecutor.java +++ b/java/java-impl/src/com/intellij/psi/impl/search/AllClassesSearchExecutor.java @@ -20,6 +20,7 @@ package com.intellij.psi.impl.search; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.util.Computable; import com.intellij.psi.*; @@ -32,8 +33,10 @@ import com.intellij.util.Processor; import com.intellij.util.QueryExecutor; import org.jetbrains.annotations.NotNull; -import java.util.Arrays; +import java.util.ArrayList; +import java.util.Collections; import java.util.Comparator; +import java.util.List; public class AllClassesSearchExecutor implements QueryExecutor { public boolean execute(@NotNull final AllClassesSearch.SearchParameters queryParameters, @NotNull final Processor consumer) { @@ -61,16 +64,34 @@ public class AllClassesSearchExecutor implements QueryExecutor() { + + final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); + if (indicator != null) { + indicator.checkCanceled(); + } + + List sorted = new ArrayList(names.length); + for (int i = 0; i < names.length; i++) { + String name = names[i]; + if (parameters.nameMatches(name)) { + sorted.add(name); + } + if (indicator != null && i % 512 == 0) { + indicator.checkCanceled(); + } + } + + if (indicator != null) { + indicator.checkCanceled(); + } + + Collections.sort(sorted, new Comparator() { public int compare(final String o1, final String o2) { return o1.compareToIgnoreCase(o2); } }); - for (final String name : names) { - if (!parameters.nameMatches(name)) continue; - + for (final String name : sorted) { ProgressManager.checkCanceled(); final PsiClass[] classes = ApplicationManager.getApplication().runReadAction(new Computable() { public PsiClass[] compute() { From ab1944d3cd10d17b8bef302f925d507e1c391860 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Mon, 8 Nov 2010 19:39:30 +0300 Subject: [PATCH 012/257] editor framgent tooltip rolled back to be non-balloon --- .../com/intellij/codeInsight/hint/EditorFragmentComponent.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/codeInsight/hint/EditorFragmentComponent.java b/platform/platform-impl/src/com/intellij/codeInsight/hint/EditorFragmentComponent.java index 9745fe537891..353aac65b256 100644 --- a/platform/platform-impl/src/com/intellij/codeInsight/hint/EditorFragmentComponent.java +++ b/platform/platform-impl/src/com/intellij/codeInsight/hint/EditorFragmentComponent.java @@ -24,6 +24,7 @@ import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.ex.FoldingModelEx; import com.intellij.openapi.util.TextRange; +import com.intellij.ui.HintHint; import com.intellij.ui.LightweightHint; import com.intellij.ui.ScreenUtil; import org.jetbrains.annotations.Nullable; @@ -152,7 +153,7 @@ public class EditorFragmentComponent extends JPanel { Point p = new Point(x, y); LightweightHint hint = new MyComponentHint(fragmentComponent); - HintManagerImpl.getInstanceImpl().showEditorHint(hint, editor, p, (hideByAnyKey ? HintManagerImpl.HIDE_BY_ANY_KEY : 0) | HintManagerImpl.HIDE_BY_TEXT_CHANGE, 0, false); + HintManagerImpl.getInstanceImpl().showEditorHint(hint, editor, p, (hideByAnyKey ? HintManagerImpl.HIDE_BY_ANY_KEY : 0) | HintManagerImpl.HIDE_BY_TEXT_CHANGE, 0, false, new HintHint(editor, p)); return hint; } From a795a7e5659e1a093fd9d5619169c3ee9d47927b Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Mon, 8 Nov 2010 20:04:08 +0300 Subject: [PATCH 013/257] IDEA-60931 Tabs color goes away on restart --- .../src/com/intellij/ui/tabs/FileColorManagerImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/ui/tabs/FileColorManagerImpl.java b/platform/lang-impl/src/com/intellij/ui/tabs/FileColorManagerImpl.java index 839af348ada3..2f6866f58737 100644 --- a/platform/lang-impl/src/com/intellij/ui/tabs/FileColorManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/ui/tabs/FileColorManagerImpl.java @@ -188,6 +188,8 @@ public class FileColorManagerImpl extends FileColorManager implements Persistent @Nullable public Color getFileColor(@NotNull final PsiFile file) { + initSharedConfigurations(); + final String colorName = myModel.getColor(file); return colorName == null ? null : getColor(colorName); } From 2d98b6c538c5e4ce6ded0a7f81926bf8fb526f2f Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Mon, 8 Nov 2010 20:27:28 +0300 Subject: [PATCH 014/257] clean up --- .../src/org/jetbrains/android/facet/AndroidFacetEditorTab.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java index 8040b125acf8..d1bef6b08245 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetEditorTab.java @@ -455,7 +455,7 @@ public class AndroidFacetEditorTab extends FacetEditorTab { myConfiguration.ASSETS_FOLDER_RELATIVE_PATH = '/' + getAndCheckRelativePath(absAssetsPath, false); String absApkPath = (String)myApkPathCombo.getComboBox().getEditor().getItem(); - if (absResPath.length() == 0) { + if (absApkPath.length() == 0) { myConfiguration.APK_PATH = ""; } else { From e4cb6a0eed1c8f8fee290446b003971dc1a6398b Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 8 Nov 2010 19:20:57 +0300 Subject: [PATCH 015/257] dispose configurables after show --- .../src/com/intellij/ide/ui/search/TraverseUIStarter.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java b/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java index 4f4fb0b1ed0b..c8959d4836cf 100644 --- a/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java +++ b/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java @@ -27,6 +27,7 @@ import com.intellij.openapi.application.ex.ApplicationEx; import com.intellij.openapi.keymap.impl.ui.KeymapConfigurable; import com.intellij.openapi.options.SearchableConfigurable; import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.JDOMUtil; import org.jdom.Document; import org.jdom.Element; @@ -98,6 +99,7 @@ public class TraverseUIStarter implements ApplicationStarter { processCodeStyleConfigurable((CodeStyleSchemesConfigurable)configurable, configurableElement); } root.addContent(configurableElement); + configurable.disposeUIResources(); } JDOMUtil.writeDocument(new Document(root), OUTPUT_PATH, "\n"); From a623497e60c72060fb9794b640563e97d7b73489 Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 8 Nov 2010 20:23:09 +0300 Subject: [PATCH 016/257] revert to prevent .iml changes --- .../src/com/intellij/openapi/roots/impl/ContentEntryImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ContentEntryImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ContentEntryImpl.java index 4f3aa9cd05ec..f7260d85a6c6 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ContentEntryImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ContentEntryImpl.java @@ -44,7 +44,7 @@ public class ContentEntryImpl extends RootModelComponentBase implements ContentE private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.SimpleContentEntryImpl"); private final VirtualFilePointer myRoot; @NonNls public static final String ELEMENT_NAME = "content"; - private final TreeSet mySourceFolders = new TreeSet(ContentFolderComparator.INSTANCE); + private final LinkedHashSet mySourceFolders = new LinkedHashSet(); private final TreeSet myExcludeFolders = new TreeSet(ContentFolderComparator.INSTANCE); private final TreeSet myExcludedOutputFolders = new TreeSet(ContentFolderComparator.INSTANCE); @NonNls public static final String URL_ATTRIBUTE = "url"; From fbf39dca255fc548e1ebdb8eaacc43ad40fa258b Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 8 Nov 2010 20:24:16 +0300 Subject: [PATCH 017/257] .iml changes --- plugins/git4idea/git4idea.iml | 2 +- plugins/hg4idea/hg4idea.iml | 2 +- plugins/properties/properties.iml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/git4idea/git4idea.iml b/plugins/git4idea/git4idea.iml index 2079f73db038..aabff7b1f236 100644 --- a/plugins/git4idea/git4idea.iml +++ b/plugins/git4idea/git4idea.iml @@ -4,9 +4,9 @@ + - diff --git a/plugins/hg4idea/hg4idea.iml b/plugins/hg4idea/hg4idea.iml index 1c036a8a3851..383f5ce51cbe 100644 --- a/plugins/hg4idea/hg4idea.iml +++ b/plugins/hg4idea/hg4idea.iml @@ -3,8 +3,8 @@ - + diff --git a/plugins/properties/properties.iml b/plugins/properties/properties.iml index cec4a8781319..2aaee73917cc 100644 --- a/plugins/properties/properties.iml +++ b/plugins/properties/properties.iml @@ -3,8 +3,8 @@ - + From 110b31053641763cf7e77a6a837248f7b9a55698 Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Mon, 8 Nov 2010 20:36:30 +0300 Subject: [PATCH 018/257] table header font AA. mousewheel font size handler. WI-3862 Query results table cells should be scaled with the font size. --- .../src/com/intellij/ui/table/JBTable.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/platform/platform-api/src/com/intellij/ui/table/JBTable.java b/platform/platform-api/src/com/intellij/ui/table/JBTable.java index bda2de982314..ad5dd5b426c1 100644 --- a/platform/platform-api/src/com/intellij/ui/table/JBTable.java +++ b/platform/platform-api/src/com/intellij/ui/table/JBTable.java @@ -89,6 +89,19 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component boolean marker = Patches.SUN_BUG_ID_4503845; // Don't remove. It's a marker for find usages } + @Override + protected JTableHeader createDefaultTableHeader() { + return new JTableHeader(columnModel) { + @Override + public void paint(Graphics g) { + if (myEnableAntialiasing) { + UISettings.setupAntialiasing(g); + } + super.paint(g); + } + }; + } + public boolean isEmpty() { return getRowCount() == 0; } From f7c661302b508ad7e62f121731c63978da77ee96 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Mon, 8 Nov 2010 21:14:28 +0300 Subject: [PATCH 019/257] change marker tooltip rolled back to be non-balloon --- .../com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java index 53d50e986dc3..d6a019e047a4 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java @@ -41,6 +41,7 @@ import com.intellij.openapi.vcs.actions.ShowNextChangeMarkerAction; import com.intellij.openapi.vcs.actions.ShowPrevChangeMarkerAction; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.ColoredSideBorder; +import com.intellij.ui.HintHint; import com.intellij.ui.HintListener; import com.intellij.ui.LightweightHint; import com.intellij.util.ui.UIUtil; @@ -208,7 +209,7 @@ public class LineStatusTrackerDrawing { HintManagerImpl.getInstanceImpl().showEditorHint(lightweightHint, editor, point, HintManagerImpl.HIDE_BY_ANY_KEY | HintManagerImpl.HIDE_BY_TEXT_CHANGE | HintManagerImpl.HIDE_BY_OTHER_HINT | HintManagerImpl.HIDE_BY_SCROLLING, - -1, false); + -1, false, new HintHint(editor, point)); } private static String getFileName(final Document document) { From 5f484eea21a2bfd602629cb14c839dba8fd089d6 Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 8 Nov 2010 21:21:14 +0300 Subject: [PATCH 020/257] type text fixed --- .../introduceVariable/IntroduceVariableBase.java | 5 +++-- .../introduceVariable/ReassignVariableUtil.java | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) 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 2801ef9574c3..bbed1f676aa0 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java @@ -480,8 +480,9 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme final VariableInplaceRenamer renamer = new VariableInplaceRenamer(elementToRename, editor){ @Override protected void addAdditionalVariables(TemplateBuilderImpl builder) { - builder.replaceElement(elementToRename.getTypeElement(), "Variable_Type", ReassignVariableUtil - .createExpression(typeSelectorManager), false, true); + final PsiTypeElement typeElement = elementToRename.getTypeElement(); + builder.replaceElement(typeElement, "Variable_Type", ReassignVariableUtil + .createExpression(typeSelectorManager, typeElement.getText()), false, true); } }; renamer.setAdvertisementText( diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java index 2eec696a185d..e0d2aa29f2e7 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java @@ -150,24 +150,24 @@ public class ReassignVariableUtil { } } - static Expression createExpression(final TypeSelectorManagerImpl typeSelectorManager) { + static Expression createExpression(final TypeSelectorManagerImpl typeSelectorManager, final String defaultText) { final PsiType[] types = typeSelectorManager.getTypesForAll(); return new Expression() { @Override public com.intellij.codeInsight.template.Result calculateResult(ExpressionContext context) { - return new TextResult(typeSelectorManager.getDefaultType().getPresentableText()); + return new TextResult(defaultText); } @Override public com.intellij.codeInsight.template.Result calculateQuickResult(ExpressionContext context) { - return new TextResult(typeSelectorManager.getDefaultType().getPresentableText()); + return new TextResult(defaultText); } @Override public LookupElement[] calculateLookupItems(ExpressionContext context) { LookupElement[] result = new LookupElement[types.length]; for (int i = 0, typesLength = types.length; i < typesLength; i++) { - result[i] = LookupElementBuilder.create(types[i].getPresentableText()); + result[i] = LookupElementBuilder.create(types[i], types[i].getPresentableText()); } return result; } From 09ff5078dc7d6a65126abf1361a76c9478ebcca1 Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 8 Nov 2010 21:28:34 +0300 Subject: [PATCH 021/257] suggest shift tab when there is another type to suggest --- .../refactoring/introduceVariable/IntroduceVariableBase.java | 2 +- .../refactoring/introduceVariable/ReassignVariableUtil.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) 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 bbed1f676aa0..b5dc13ba4f83 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java @@ -486,7 +486,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme } }; renamer.setAdvertisementText( - ReassignVariableUtil.getAdvertisementText(editor, declarationStatement, elementToRename.getType())); + ReassignVariableUtil.getAdvertisementText(editor, declarationStatement, elementToRename.getType(), typeSelectorManager.getTypesForAll())); renamer.performInplaceRename(false, new LinkedHashSet(Arrays.asList(suggestedName.names)), new Consumer() { @Override public void consume(Boolean apply) { diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java index e0d2aa29f2e7..9e76662587ed 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java @@ -174,7 +174,8 @@ public class ReassignVariableUtil { }; } - static String getAdvertisementText(Editor editor, PsiDeclarationStatement declaration, PsiType type) { + @Nullable + static String getAdvertisementText(Editor editor, PsiDeclarationStatement declaration, PsiType type, PsiType[] typesForAll) { final VariablesProcessor processor = findVariablesOfType(editor, declaration, type); if (processor.size() > 0) { final Keymap keymap = KeymapManager.getInstance().getActiveKeymap(); @@ -183,6 +184,6 @@ public class ReassignVariableUtil { return "Press " + shortcuts[0] + " to reassign existing variable"; } } - return "Press Shift Tab to change type"; + return typesForAll.length > 1 ? "Press Shift Tab to change type" : null; } } From 1991d544cc107ad3128547f8def1e636dac95bfa Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 8 Nov 2010 18:40:34 +0300 Subject: [PATCH 022/257] Missed test data added --- plugins/ant/tests/data/psi/Dirname_u.txt | 57 ++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 plugins/ant/tests/data/psi/Dirname_u.txt diff --git a/plugins/ant/tests/data/psi/Dirname_u.txt b/plugins/ant/tests/data/psi/Dirname_u.txt new file mode 100644 index 000000000000..ea49effbd1e5 --- /dev/null +++ b/plugins/ant/tests/data/psi/Dirname_u.txt @@ -0,0 +1,57 @@ +XmlFile:Dirname.ant + PsiElement(XML_DOCUMENT) + PsiElement(XML_PROLOG) + + XmlTag:project + XmlToken:XML_START_TAG_START('<') + XmlToken:XML_NAME('project') + PsiWhiteSpace(' ') + PsiElement(XML_ATTRIBUTE) + XmlToken:XML_NAME('default') + XmlToken:XML_EQ('=') + PsiElement(XML_ATTRIBUTE_VALUE) + XmlToken:XML_ATTRIBUTE_VALUE_START_DELIMITER('"') + XmlToken:XML_ATTRIBUTE_VALUE_TOKEN('A') + XmlToken:XML_ATTRIBUTE_VALUE_END_DELIMITER('"') + XmlToken:XML_TAG_END('>') + XmlText + PsiWhiteSpace('\n ') + XmlTag:dirname + XmlToken:XML_START_TAG_START('<') + XmlToken:XML_NAME('dirname') + PsiWhiteSpace(' ') + PsiElement(XML_ATTRIBUTE) + XmlToken:XML_NAME('property') + XmlToken:XML_EQ('=') + PsiElement(XML_ATTRIBUTE_VALUE) + XmlToken:XML_ATTRIBUTE_VALUE_START_DELIMITER('"') + XmlToken:XML_ATTRIBUTE_VALUE_TOKEN('prop') + XmlToken:XML_ATTRIBUTE_VALUE_END_DELIMITER('"') + PsiWhiteSpace(' ') + PsiElement(XML_ATTRIBUTE) + XmlToken:XML_NAME('file') + XmlToken:XML_EQ('=') + PsiElement(XML_ATTRIBUTE_VALUE) + XmlToken:XML_ATTRIBUTE_VALUE_START_DELIMITER('"') + XmlToken:XML_ATTRIBUTE_VALUE_TOKEN('${ant.file}') + XmlToken:XML_ATTRIBUTE_VALUE_END_DELIMITER('"') + XmlToken:XML_EMPTY_ELEMENT_END('/>') + XmlText + PsiWhiteSpace('\n ') + XmlTag:target + XmlToken:XML_START_TAG_START('<') + XmlToken:XML_NAME('target') + PsiWhiteSpace(' ') + PsiElement(XML_ATTRIBUTE) + XmlToken:XML_NAME('name') + XmlToken:XML_EQ('=') + PsiElement(XML_ATTRIBUTE_VALUE) + XmlToken:XML_ATTRIBUTE_VALUE_START_DELIMITER('"') + XmlToken:XML_ATTRIBUTE_VALUE_TOKEN('A') + XmlToken:XML_ATTRIBUTE_VALUE_END_DELIMITER('"') + XmlToken:XML_EMPTY_ELEMENT_END('/>') + XmlText + PsiWhiteSpace('\n') + XmlToken:XML_END_TAG_START('') \ No newline at end of file From cb1db6171b604c8d917843e9159be65b365fea84 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 8 Nov 2010 21:06:30 +0300 Subject: [PATCH 023/257] IDEA-57674 (parameterized explicit constructor call) --- .../lang/java/parser/ExpressionParser.java | 36 +++++++++++++------ .../PinesInReferenceExpression2.txt | 17 +++++++++ .../parser/partial/ExpressionParserTest.java | 1 + 3 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 java/java-tests/testData/psi/parser-partial/expressions/PinesInReferenceExpression2.txt diff --git a/java/java-impl/src/com/intellij/lang/java/parser/ExpressionParser.java b/java/java-impl/src/com/intellij/lang/java/parser/ExpressionParser.java index ac329b05bfea..a7d00b29c069 100644 --- a/java/java-impl/src/com/intellij/lang/java/parser/ExpressionParser.java +++ b/java/java-impl/src/com/intellij/lang/java/parser/ExpressionParser.java @@ -59,6 +59,7 @@ public class ExpressionParser { private static final TokenSet ARGS_LIST_END = TokenSet.create(JavaTokenType.RPARENTH, JavaTokenType.RBRACE, JavaTokenType.RBRACKET); private static final TokenSet ARGS_LIST_CONTINUE = TokenSet.create( JavaTokenType.IDENTIFIER, TokenType.BAD_CHARACTER, JavaTokenType.COMMA, JavaTokenType.INTEGER_LITERAL, JavaTokenType.STRING_LITERAL); + private static final TokenSet CONSTRUCTOR_CALL = TokenSet.create(JavaTokenType.THIS_KEYWORD, JavaTokenType.SUPER_KEYWORD); private ExpressionParser() { } @@ -553,18 +554,33 @@ public class ExpressionParser { beforeAnnotation.drop(); } - if (tokenType == JavaTokenType.THIS_KEYWORD) { - final PsiBuilder.Marker expr = builder.mark(); - builder.mark().done(JavaElementType.REFERENCE_PARAMETER_LIST); - builder.advanceLexer(); - expr.done(builder.getTokenType() != JavaTokenType.LPARENTH ? JavaElementType.THIS_EXPRESSION : JavaElementType.REFERENCE_EXPRESSION); - return expr; + PsiBuilder.Marker expr = null; + if (tokenType == JavaTokenType.LT) { + expr = builder.mark(); + + if (!ReferenceParser.parseReferenceParameterList(builder, false, false)) { + expr.rollbackTo(); + return null; + } + + tokenType = builder.getTokenType(); + if (!CONSTRUCTOR_CALL.contains(tokenType)) { + expr.rollbackTo(); + return null; + } } - if (tokenType == JavaTokenType.SUPER_KEYWORD) { - final PsiBuilder.Marker expr = builder.mark(); - builder.mark().done(JavaElementType.REFERENCE_PARAMETER_LIST); + + if (CONSTRUCTOR_CALL.contains(tokenType)) { + if (expr == null) { + expr = builder.mark(); + builder.mark().done(JavaElementType.REFERENCE_PARAMETER_LIST); + } builder.advanceLexer(); - expr.done(builder.getTokenType() != JavaTokenType.LPARENTH ? JavaElementType.SUPER_EXPRESSION : JavaElementType.REFERENCE_EXPRESSION); + expr.done(builder.getTokenType() == JavaTokenType.LPARENTH + ? JavaElementType.REFERENCE_EXPRESSION + : tokenType == JavaTokenType.THIS_KEYWORD + ? JavaElementType.THIS_EXPRESSION + : JavaElementType.SUPER_EXPRESSION); return expr; } if (tokenType == JavaTokenType.NEW_KEYWORD) { diff --git a/java/java-tests/testData/psi/parser-partial/expressions/PinesInReferenceExpression2.txt b/java/java-tests/testData/psi/parser-partial/expressions/PinesInReferenceExpression2.txt new file mode 100644 index 000000000000..52b37d3ab61b --- /dev/null +++ b/java/java-tests/testData/psi/parser-partial/expressions/PinesInReferenceExpression2.txt @@ -0,0 +1,17 @@ +PsiJavaFile:PinesInReferenceExpression2.java + PsiMethodCallExpression:super(null) + PsiReferenceExpression:super + PsiReferenceParameterList + PsiJavaToken:LT('<') + PsiTypeElement:String + PsiJavaCodeReferenceElement:String + PsiIdentifier:String('String') + PsiReferenceParameterList + + PsiJavaToken:GT('>') + PsiKeyword:super('super') + PsiExpressionList + PsiJavaToken:LPARENTH('(') + PsiLiteralExpression:null + PsiJavaToken:NULL_KEYWORD('null') + PsiJavaToken:RPARENTH(')') \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/ExpressionParserTest.java b/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/ExpressionParserTest.java index c5fb275f7855..6b294d9083fc 100644 --- a/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/ExpressionParserTest.java +++ b/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/ExpressionParserTest.java @@ -92,6 +92,7 @@ public class ExpressionParserTest extends JavaParsingTestCase { public void testPinesInReferenceExpression0() { doParserTest("Collections.sort(null)"); } public void testPinesInReferenceExpression1() { doParserTest("this.sort(null)"); } + public void testPinesInReferenceExpression2() { doParserTest("super(null)"); } public void testGE0() { doParserTest("x >>>= 8 >> 2"); } public void testGE1() { doParserTest("x >= 2"); } From 0c39d517a5d959941f51e98350612963cc8ca405 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 8 Nov 2010 21:40:48 +0300 Subject: [PATCH 024/257] IDEA-56188 (trailing comma in annotation value array initializer) --- .../lang/java/parser/DeclarationParser.java | 4 +++- .../annotations/ExtraCommaInList.txt | 21 +++++++++++++++++++ .../parser/partial/AnnotationParserTest.java | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/psi/parser-partial/annotations/ExtraCommaInList.txt diff --git a/java/java-impl/src/com/intellij/lang/java/parser/DeclarationParser.java b/java/java-impl/src/com/intellij/lang/java/parser/DeclarationParser.java index ff9d1da681b8..47b60ef7d599 100644 --- a/java/java-impl/src/com/intellij/lang/java/parser/DeclarationParser.java +++ b/java/java-impl/src/com/intellij/lang/java/parser/DeclarationParser.java @@ -817,7 +817,9 @@ public class DeclarationParser { break; } else if (expect(builder, JavaTokenType.COMMA)) { - parseAnnotationValue(builder); + if (builder.getTokenType() != JavaTokenType.RBRACE) { + parseAnnotationValue(builder); + } } else { error(builder, JavaErrorMessages.message("expected.rbrace")); diff --git a/java/java-tests/testData/psi/parser-partial/annotations/ExtraCommaInList.txt b/java/java-tests/testData/psi/parser-partial/annotations/ExtraCommaInList.txt new file mode 100644 index 000000000000..c58fc1971df5 --- /dev/null +++ b/java/java-tests/testData/psi/parser-partial/annotations/ExtraCommaInList.txt @@ -0,0 +1,21 @@ +PsiJavaFile:ExtraCommaInList.java + PsiAnnotation + PsiJavaToken:AT('@') + PsiJavaCodeReferenceElement:Anno + PsiIdentifier:Anno('Anno') + PsiReferenceParameterList + + PsiAnnotationParameterList + PsiJavaToken:LPARENTH('(') + PsiNameValuePair + PsiArrayInitializerMemberValue:{0, 1,} + PsiJavaToken:LBRACE('{') + PsiLiteralExpression:0 + PsiJavaToken:INTEGER_LITERAL('0') + PsiJavaToken:COMMA(',') + PsiWhiteSpace(' ') + PsiLiteralExpression:1 + PsiJavaToken:INTEGER_LITERAL('1') + PsiJavaToken:COMMA(',') + PsiJavaToken:RBRACE('}') + PsiJavaToken:RPARENTH(')') diff --git a/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/AnnotationParserTest.java b/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/AnnotationParserTest.java index 6cad51311ea7..e0a38e2a58dd 100644 --- a/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/AnnotationParserTest.java +++ b/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/AnnotationParserTest.java @@ -33,6 +33,7 @@ public class AnnotationParserTest extends JavaParsingTestCase { public void testArray() { doParserTest("@Endorsers({\"Children\", \"Unscrupulous dentists\"})"); } public void testNested() { doParserTest("@Author(@Name(first=\"Eugene\", second=\"Wampirchik\"))"); } public void testQualifiedAnnotation() { doParserTest("@org.jetbrains.annotations.Nullable"); } + public void testExtraCommaInList() { doParserTest("@Anno({0, 1,})"); } public void testParameterizedAnnotation () { doParserTest("@Nullable"); } public void testFirstNameMissed() { doParserTest("@Anno(value1, param2=value2)"); } From 6df7ba3e8e9937b03f6178830f2996d0c277a1cd Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 8 Nov 2010 19:55:24 +0100 Subject: [PATCH 025/257] more accurate "unnecessary 'this' qualifier" inspection, less code --- .../ConstantIfStatementInspection.java | 104 ++------ .../ig/psiutils/VariableSearchUtils.java | 231 +++--------------- .../ig/style/UnnecessaryThisInspection.java | 51 +++- .../UnnecessaryThisInspection.java | 16 ++ .../style/unnecessary_this/expected.xml | 8 + .../style/UnnecessaryThisInspectionTest.java | 3 +- 6 files changed, 110 insertions(+), 303 deletions(-) diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/controlflow/ConstantIfStatementInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/controlflow/ConstantIfStatementInspection.java index 159382a39c89..840feb65f3ac 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/controlflow/ConstantIfStatementInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/controlflow/ConstantIfStatementInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2010 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. @@ -26,33 +26,36 @@ import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.psiutils.BoolUtils; +import com.siyeh.ig.psiutils.VariableSearchUtils; import org.jetbrains.annotations.NotNull; -import java.util.HashSet; -import java.util.Set; - public class ConstantIfStatementInspection extends BaseInspection { + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "constant.if.statement.display.name"); } + @Override public boolean isEnabledByDefault() { return true; } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "constant.if.statement.problem.descriptor"); } + @Override public BaseInspectionVisitor buildVisitor() { return new ConstantIfStatementVisitor(); } + @Override public InspectionGadgetsFix buildFix(Object... infos) { //if (PsiUtil.isInJspFile(location)) { // return null; @@ -103,7 +106,8 @@ public class ConstantIfStatementInspection extends BaseInspection { final PsiCodeBlock block = ((PsiBlockStatement)branch).getCodeBlock(); final boolean hasConflicts = - containsConflictingDeclarations(block, parentBlock); + VariableSearchUtils.containsConflictingDeclarations( + block, parentBlock); if (hasConflicts) { final String elseText = branch.getText(); replaceStatement(statement, elseText); @@ -112,9 +116,12 @@ public class ConstantIfStatementInspection extends BaseInspection { final PsiStatement[] statements = block.getStatements(); if (statements.length > 0) { assert containingElement != null; - final PsiElement added = containingElement.addRangeBefore(statements[0], statements[statements.length - 1], statement); + final PsiElement added = + containingElement.addRangeBefore(statements[0], + statements[statements.length - 1], statement); final Project project = statement.getProject(); - final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project); + final CodeStyleManager codeStyleManager = + CodeStyleManager.getInstance(project); codeStyleManager.reformat(added); } statement.delete(); @@ -124,43 +131,6 @@ public class ConstantIfStatementInspection extends BaseInspection { replaceStatement(statement, elseText); } } - - private static boolean containsConflictingDeclarations( - PsiCodeBlock block, PsiCodeBlock parentBlock) { - final PsiStatement[] statements = block.getStatements(); - final Set declaredVars = new HashSet(); - for (final PsiStatement statement : statements) { - if (statement instanceof PsiDeclarationStatement) { - final PsiDeclarationStatement declaration = - (PsiDeclarationStatement)statement; - final PsiElement[] vars = declaration.getDeclaredElements(); - for (PsiElement var : vars) { - if (var instanceof PsiLocalVariable) { - declaredVars.add(var); - } - } - } - } - for (Object declaredVar : declaredVars) { - final PsiLocalVariable variable = - (PsiLocalVariable)declaredVar; - final String variableName = variable.getName(); - if (conflictingDeclarationExists(variableName, parentBlock, - block)) { - return true; - } - } - return false; - } - - private static boolean conflictingDeclarationExists( - String name, PsiCodeBlock parentBlock, - PsiCodeBlock exceptBlock) { - final ConflictingDeclarationVisitor visitor = - new ConflictingDeclarationVisitor(name, exceptBlock); - parentBlock.accept(visitor); - return visitor.hasConflictingDeclaration(); - } } private static class ConstantIfStatementVisitor @@ -181,50 +151,4 @@ public class ConstantIfStatementInspection extends BaseInspection { } } } - - private static class ConflictingDeclarationVisitor - extends JavaRecursiveElementVisitor { - - private final String variableName; - private final PsiCodeBlock exceptBlock; - private boolean hasConflictingDeclaration = false; - - ConflictingDeclarationVisitor(String variableName, - PsiCodeBlock exceptBlock) { - super(); - this.variableName = variableName; - this.exceptBlock = exceptBlock; - } - - @Override public void visitElement(@NotNull PsiElement element) { - if (!hasConflictingDeclaration) { - super.visitElement(element); - } - } - - @Override public void visitCodeBlock(PsiCodeBlock block) { - if (hasConflictingDeclaration) { - return; - } - if (block.equals(exceptBlock)) { - return; - } - super.visitCodeBlock(block); - } - - @Override public void visitVariable(PsiVariable variable) { - if (hasConflictingDeclaration) { - return; - } - super.visitVariable(variable); - final String name = variable.getName(); - if (name != null && name.equals(variableName)) { - hasConflictingDeclaration = true; - } - } - - public boolean hasConflictingDeclaration() { - return hasConflictingDeclaration; - } - } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/VariableSearchUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/VariableSearchUtils.java index a1ba06ec29ee..987c86b287d4 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/VariableSearchUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/VariableSearchUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2010 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. @@ -15,226 +15,55 @@ */ package com.siyeh.ig.psiutils; +import com.intellij.openapi.project.Project; import com.intellij.psi.*; -import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.HashSet; -import java.util.Set; public class VariableSearchUtils { private VariableSearchUtils() {} - public static boolean existsLocalOrParameter(@NotNull String variableName, - @Nullable PsiElement context) { - if (context == null) { - return false; - } - if (existsParameter(variableName, context)) { - return true; - } - if (existsLocal(variableName, context)) { - return true; - } - if (existsCatchSectionLocal(variableName, context)) { - return true; - } - if (existsForLoopLocal(variableName, context)) { - return true; - } - return existsForeachLoopLocal(variableName, context); - } - - private static boolean existsParameter(@NotNull String variableName, - PsiElement context) { - PsiMethod ancestor = - PsiTreeUtil.getParentOfType(context, PsiMethod.class); - while (ancestor != null) { - final PsiParameterList parameterList = ancestor.getParameterList(); - final PsiParameter[] parameters = parameterList.getParameters(); - for (final PsiParameter parameter : parameters) { - final String parameterName = parameter.getName(); - if (variableName.equals(parameterName)) { - return true; - } - } - ancestor = PsiTreeUtil.getParentOfType(ancestor, PsiMethod.class); - } - return false; - } - - private static boolean existsLocal(@NotNull String variableName, - PsiElement context) { - PsiCodeBlock ancestor = - PsiTreeUtil.getParentOfType(context, PsiCodeBlock.class); - while (ancestor != null) { - final PsiStatement[] statements = ancestor.getStatements(); - for (final PsiStatement statement : statements) { - if (statement instanceof PsiDeclarationStatement) { - final PsiDeclarationStatement declarationStatement = - (PsiDeclarationStatement) statement; - final PsiElement[] elements = - declarationStatement.getDeclaredElements(); - for (PsiElement element : elements) { - if (!(element instanceof PsiLocalVariable)) { - continue; - } - final PsiLocalVariable localVariable = - (PsiLocalVariable) element; - final String localVariableName = - localVariable.getName(); - if(variableName.equals(localVariableName)) { - return true; - } - } - } - } - ancestor = - PsiTreeUtil.getParentOfType(ancestor, PsiCodeBlock.class); - } - return false; - } - - private static boolean existsCatchSectionLocal(@NotNull String variableName, - PsiElement context) { - PsiCatchSection catchSectionAncestor = - PsiTreeUtil.getParentOfType(context, PsiCatchSection.class); - while (catchSectionAncestor != null) { - final PsiParameter parameter = - catchSectionAncestor.getParameter(); - if (parameter != null) { - final String parameterName = parameter.getName(); - if (variableName.equals(parameterName)) { - return true; - } - } - catchSectionAncestor = - PsiTreeUtil.getParentOfType(catchSectionAncestor, - PsiCatchSection.class); - } - return false; - } - - private static boolean existsForLoopLocal(@NotNull String variableName, - PsiElement context) { - PsiForStatement forLoopAncestor = - PsiTreeUtil.getParentOfType(context, PsiForStatement.class); - while (forLoopAncestor != null) { - final PsiStatement initialization = - forLoopAncestor.getInitialization(); - if (initialization instanceof PsiDeclarationStatement) { - final PsiDeclarationStatement declarationStatement = - (PsiDeclarationStatement) initialization; - final PsiElement[] elements = - declarationStatement.getDeclaredElements(); - for (PsiElement element : elements) { - final PsiLocalVariable localVariable = - (PsiLocalVariable) element; - final String localVariableName = localVariable.getName(); - if (variableName.equals(localVariableName)) { - return true; - } - } - } - forLoopAncestor = PsiTreeUtil.getParentOfType(forLoopAncestor, - PsiForStatement.class); - } - return false; - } - - private static boolean existsForeachLoopLocal(@NotNull String variableName, - PsiElement context) { - PsiForeachStatement forLoopAncestor = - PsiTreeUtil.getParentOfType(context, PsiForeachStatement.class); - while (forLoopAncestor != null) { - final PsiParameter parameter = - forLoopAncestor.getIterationParameter(); - final String parameterName = parameter.getName(); - if (variableName.equals(parameterName)) { - return true; - } - forLoopAncestor = PsiTreeUtil.getParentOfType(forLoopAncestor, - PsiForeachStatement.class); - } - return false; + public static boolean variableNameResolvesToTarget( + @NotNull String variableName, @NotNull PsiVariable target, + @NotNull PsiElement context) { + + final Project project = context.getProject(); + final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); + final PsiResolveHelper resolveHelper = psiFacade.getResolveHelper(); + final PsiVariable variable = + resolveHelper.resolveAccessibleReferencedVariable( + variableName, context); + return target.equals(variable); } public static boolean containsConflictingDeclarations( - PsiCodeBlock block, PsiCodeBlock parentBlock){ + PsiCodeBlock block, PsiCodeBlock parentBlock) { final PsiStatement[] statements = block.getStatements(); - final Set variableNames = new HashSet(); - for(final PsiStatement statement : statements){ + final Project project = block.getProject(); + final JavaPsiFacade facade = JavaPsiFacade.getInstance(project); + final PsiResolveHelper resolveHelper = facade.getResolveHelper(); + for (final PsiStatement statement : statements) { if (!(statement instanceof PsiDeclarationStatement)) { continue; } final PsiDeclarationStatement declaration = - (PsiDeclarationStatement) statement; - final PsiElement[] declaredElements = + (PsiDeclarationStatement)statement; + final PsiElement[] variables = declaration.getDeclaredElements(); - for(PsiElement declaredElement : declaredElements){ - if (!(declaredElement instanceof PsiLocalVariable)) { + for (PsiElement variable : variables) { + if (!(variable instanceof PsiLocalVariable)) { continue; } - final PsiLocalVariable variable = - (PsiLocalVariable)declaredElement; - final String variableName = variable.getName(); - if (variableName == null) { - continue; + final PsiLocalVariable localVariable = + (PsiLocalVariable) variable; + final PsiVariable target = + resolveHelper.resolveAccessibleReferencedVariable( + localVariable.getName(), parentBlock); + if (target != null) { + return true; } - variableNames.add(variableName); } } - final ConflictingDeclarationVisitor visitor = - new ConflictingDeclarationVisitor(variableNames, block); - parentBlock.accept(visitor); - return visitor.hasConflictingDeclaration(); - } - - private static class ConflictingDeclarationVisitor - extends JavaRecursiveElementVisitor{ - - private final Set variableNames; - private final PsiCodeBlock exceptBlock; - private boolean hasConflictingDeclaration = false; - - ConflictingDeclarationVisitor(@NotNull Set variableNames, - PsiCodeBlock exceptBlock){ - this.variableNames = variableNames; - this.exceptBlock = exceptBlock; - } - - @Override public void visitElement(@NotNull PsiElement element){ - if (hasConflictingDeclaration) { - return; - } - super.visitElement(element); - } - - @Override public void visitCodeBlock(PsiCodeBlock block){ - if(hasConflictingDeclaration){ - return; - } - if(block.equals(exceptBlock)){ - return; - } - super.visitCodeBlock(block); - } - - @Override public void visitVariable(@NotNull PsiVariable variable){ - if(hasConflictingDeclaration){ - return; - } - super.visitVariable(variable); - final String name = variable.getName(); - if(variableNames.contains(name)){ - hasConflictingDeclaration = true; - } - } - - public boolean hasConflictingDeclaration(){ - return hasConflictingDeclaration; - } + return false; } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryThisInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryThisInspection.java index 2dd7625f998f..0c9cf1d6a04a 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryThisInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryThisInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2010 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. @@ -18,6 +18,7 @@ package com.siyeh.ig.style; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; @@ -29,17 +30,20 @@ import org.jetbrains.annotations.NotNull; public class UnnecessaryThisInspection extends BaseInspection { + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message("unnecessary.this.display.name"); } + @Override @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( "unnecessary.this.problem.descriptor"); } + @Override public InspectionGadgetsFix buildFix(Object... infos) { return new UnnecessaryThisFix(); } @@ -66,6 +70,7 @@ public class UnnecessaryThisInspection extends BaseInspection { } } + @Override public BaseInspectionVisitor buildVisitor() { return new UnnecessaryThisVisitor(); } @@ -103,8 +108,13 @@ public class UnnecessaryThisInspection extends BaseInspection { registerError(qualifierExpression); return; } - if (VariableSearchUtils.existsLocalOrParameter(referenceName, - expression)) { + final PsiElement target = expression.resolve(); + if (!(target instanceof PsiVariable)) { + return; + } + final PsiVariable variable = (PsiVariable) target; + if (!VariableSearchUtils.variableNameResolvesToTarget( + referenceName, variable, expression)) { return; } registerError(thisExpression); @@ -124,24 +134,43 @@ public class UnnecessaryThisInspection extends BaseInspection { final String methodName = calledMethod.getName(); PsiClass parentClass = ClassUtils.getContainingClass(expression); + final Project project = expression.getProject(); + final JavaPsiFacade psiFacade = + JavaPsiFacade.getInstance(project); + final PsiResolveHelper resolveHelper = + psiFacade.getResolveHelper(); while (parentClass != null) { if (qualifierName.equals(parentClass.getName())) { registerError(thisExpression); } - //resolve will point to any _accessible_ method with the same name final PsiMethod[] methods = - parentClass.findMethodsByName(methodName, - true); - //todo: filter only accessible methods - if (methods.length > 0) { - return; + parentClass.findMethodsByName(methodName, true); + for (PsiMethod method : methods) { + final PsiClass containingClass = + method.getContainingClass(); + if (resolveHelper.isAccessible(method, + expression, containingClass)) { + if (method.hasModifierProperty( + PsiModifier.PRIVATE) && + !PsiTreeUtil.isAncestor(containingClass, + expression, true)) { + continue; + } + return; + } + } parentClass = ClassUtils.getContainingClass(parentClass); } } else { - if (VariableSearchUtils.existsLocalOrParameter(referenceName, - expression)) { + final PsiElement target = expression.resolve(); + if (!(target instanceof PsiVariable)) { + return; + } + final PsiVariable variable = (PsiVariable) target; + if (!VariableSearchUtils.variableNameResolvesToTarget( + referenceName, variable, expression)) { return; } PsiClass parentClass = diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_this/UnnecessaryThisInspection.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_this/UnnecessaryThisInspection.java index 4552710b662c..4edef3d03e70 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_this/UnnecessaryThisInspection.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_this/UnnecessaryThisInspection.java @@ -53,4 +53,20 @@ public class UnnecessaryThisInspection throwable.printStackTrace(); } } + + public void foo(String s) {} + + class D{ + + private void foo(String s) {} + } + class C extends D { + + class Box { + + void bar() { + UnnecessaryThisInspection.this.foo(""); + } + } + } } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_this/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_this/expected.xml index 7491a3413bde..d620f795222c 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_this/expected.xml +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_this/expected.xml @@ -14,4 +14,12 @@ Unnecessary 'this' qualifier <code>this</code> is unnecessary in this context #loc + + + UnnecessaryThisInspection.java + 68 + Unnecessary 'this' qualifier + <code>UnnecessaryThisInspection.this</code> is unnecessary in this context #loc + + \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryThisInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryThisInspectionTest.java index 04c361bf5325..5e36cc3bd064 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryThisInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryThisInspectionTest.java @@ -5,6 +5,7 @@ import com.IGInspectionTestCase; public class UnnecessaryThisInspectionTest extends IGInspectionTestCase { public void test() throws Exception { - doTest("com/siyeh/igtest/style/unnecessary_this", new UnnecessaryThisInspection()); + doTest("com/siyeh/igtest/style/unnecessary_this", + new UnnecessaryThisInspection()); } } \ No newline at end of file From b25bd94e5a861ffdea7cc9971b42932ad9719fa0 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Mon, 8 Nov 2010 21:54:17 +0300 Subject: [PATCH 026/257] Having a directory in initial startup costs >5megs in ClasspathCache resource map filled with results of recursive symlinks walking in JWS plugin. --- build/conf/mac/Contents/Info.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/conf/mac/Contents/Info.plist b/build/conf/mac/Contents/Info.plist index 5ac4640b0767..25e799c35539 100644 --- a/build/conf/mac/Contents/Info.plist +++ b/build/conf/mac/Contents/Info.plist @@ -42,7 +42,7 @@ Java ClassPath - $APP_PACKAGE/lib/bootstrap.jar:$APP_PACKAGE/lib/extensions.jar:$APP_PACKAGE/lib/util.jar:$APP_PACKAGE/lib/jdom.jar:$APP_PACKAGE/lib/log4j.jar:/System/Library/Java + $APP_PACKAGE/lib/bootstrap.jar:$APP_PACKAGE/lib/extensions.jar:$APP_PACKAGE/lib/util.jar:$APP_PACKAGE/lib/jdom.jar:$APP_PACKAGE/lib/log4j.jar JVMVersion @@jdk_req@@ From 4b6cbf3185c74e6502ec64c7d95f611eaafa0bc6 Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Mon, 8 Nov 2010 21:31:43 +0300 Subject: [PATCH 027/257] extract method --- .../com/intellij/openapi/editor/impl/EditorImpl.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index c30a0970c3a8..33a40608216c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -5173,6 +5173,12 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi info.put("caret", visual.getLine() + ":" + visual.getColumn()); } + public static boolean isChangeFontSize(MouseWheelEvent e) { + return SystemInfo.isMac + ? !e.isControlDown() && e.isMetaDown() && !e.isAltDown() && !e.isShiftDown() + : e.isControlDown() && !e.isMetaDown() && !e.isAltDown() && !e.isShiftDown(); + } + private class MyScrollPane extends JBScrollPane { @@ -5182,10 +5188,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi protected void processMouseWheelEvent(MouseWheelEvent e) { if (mySettings.isWheelFontChangeEnabled()) { - boolean changeFontSize = SystemInfo.isMac - ? !e.isControlDown() && e.isMetaDown() && !e.isAltDown() && !e.isShiftDown() - : e.isControlDown() && !e.isMetaDown() && !e.isAltDown() && !e.isShiftDown(); - if (changeFontSize) { + if (isChangeFontSize(e)) { setFontSize(myScheme.getEditorFontSize() + e.getWheelRotation()); return; } From 8b758ade5dd2918bcb8fea2f099cd147312f7190 Mon Sep 17 00:00:00 2001 From: nik Date: Mon, 8 Nov 2010 17:58:05 +0300 Subject: [PATCH 028/257] 'navigate' and 'fix' actions implemented for new project structure errors --- .../ui/configuration/ConfigurationError.java | 4 +- .../ConfigurationErrorsComponent.java | 25 +++--- .../ui/configuration/ProjectConfigurable.java | 2 +- .../ProjectStructureConfigurable.java | 20 ++++- .../artifacts/ArtifactProblemDescription.java | 10 +-- .../artifacts/ArtifactProblemsHolderImpl.java | 6 +- .../libraryEditor/LibraryRootsComponent.java | 10 ++- .../projectRoot/LibraryConfigurable.java | 6 ++ .../daemon/ConfigurationErrorQuickFix.java | 30 +++++++ .../LibraryProjectStructureElement.java | 80 ++++++++++++++++++- .../daemon/ModuleProjectStructureElement.java | 14 +++- .../daemon/ProjectConfigurationProblem.java | 71 ++++++++++++++++ .../daemon/ProjectConfigurationProblems.java | 16 +--- .../ProjectStructureProblemDescription.java | 26 +++++- .../ProjectStructureProblemsHolder.java | 6 +- .../ProjectStructureProblemsHolderImpl.java | 12 ++- .../roots/impl/libraries/LibraryEx.java | 6 +- .../roots/impl/libraries/LibraryImpl.java | 11 ++- 18 files changed, 297 insertions(+), 58 deletions(-) create mode 100644 java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ConfigurationErrorQuickFix.java create mode 100644 java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblem.java diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ConfigurationError.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ConfigurationError.java index fdd29a300176..66a8de47a85a 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ConfigurationError.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ConfigurationError.java @@ -17,6 +17,8 @@ package com.intellij.openapi.roots.ui.configuration; import org.jetbrains.annotations.NotNull; +import javax.swing.*; + /** * User: spLeaner */ @@ -65,7 +67,7 @@ public abstract class ConfigurationError implements Comparable implements D } @Override - public void fix() { + public void fix(JComponent contextComponent) { } @Override diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java index f7a6784e2e3d..fac45969b2a7 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java @@ -364,6 +364,10 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se return navigateTo(place, requestFocus); } + public Place createModulePlace(@NotNull Module module) { + return createPlaceFor(myModulesConfig).putPath(ModuleStructureConfigurable.TREE_OBJECT, module); + } + public ActionCallback select(@Nullable final Facet facetToSelect, final boolean requestFocus) { Place place = createPlaceFor(myModulesConfig); if (facetToSelect != null) { @@ -379,17 +383,27 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se } public ActionCallback selectProjectOrGlobalLibrary(@NotNull Library library, boolean requestFocus) { - Place place = createPlaceFor(getConfigurableFor(library)); - place.putPath(BaseStructureConfigurable.TREE_NAME, library.getName()); + Place place = createProjectOrGlobalLibraryPlace(library); return navigateTo(place, requestFocus); } + public Place createProjectOrGlobalLibraryPlace(Library library) { + Place place = createPlaceFor(getConfigurableFor(library)); + place.putPath(BaseStructureConfigurable.TREE_NAME, library.getName()); + return place; + } + public ActionCallback select(@Nullable Artifact artifact, boolean requestFocus) { + Place place = createArtifactPlace(artifact); + return navigateTo(place, requestFocus); + } + + public Place createArtifactPlace(Artifact artifact) { Place place = createPlaceFor(myArtifactsStructureConfigurable); if (artifact != null) { place.putPath(BaseStructureConfigurable.TREE_NAME, artifact.getName()); } - return navigateTo(place, requestFocus); + return place; } public ActionCallback select(@NotNull LibraryOrderEntry libraryOrderEntry, final boolean requestFocus) { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemDescription.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemDescription.java index 8595333d1d6f..20317b52c8d1 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemDescription.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemDescription.java @@ -15,9 +15,11 @@ */ package com.intellij.openapi.roots.ui.configuration.artifacts; +import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ConfigurationErrorQuickFix; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemDescription; import com.intellij.packaging.elements.PackagingElement; import com.intellij.packaging.ui.ArtifactProblemQuickFix; +import com.intellij.ui.navigation.Place; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -31,15 +33,11 @@ public class ArtifactProblemDescription extends ProjectStructureProblemDescripti private List myQuickFixes; private List> myPathToPlace; - public ArtifactProblemDescription(@NotNull String message, @NotNull Severity severity) { - this(message, severity, null, Collections.emptyList()); - } - public ArtifactProblemDescription(@NotNull String message, @NotNull Severity severity, @Nullable List> pathToPlace, - @NotNull List quickFixes) { - super(message, severity); + @NotNull List quickFixes, @NotNull Place place) { + super(message, null, severity, place, Collections.emptyList()); myPathToPlace = pathToPlace; myQuickFixes = quickFixes; } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemsHolderImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemsHolderImpl.java index 4cca595a799c..380260c8885f 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemsHolderImpl.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemsHolderImpl.java @@ -15,12 +15,14 @@ */ package com.intellij.openapi.roots.ui.configuration.artifacts; +import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemDescription; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemsHolder; import com.intellij.packaging.elements.PackagingElement; import com.intellij.packaging.impl.ui.ArtifactProblemsHolderBase; import com.intellij.packaging.ui.ArtifactEditorContext; import com.intellij.packaging.ui.ArtifactProblemQuickFix; +import com.intellij.ui.navigation.Place; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -44,7 +46,9 @@ public class ArtifactProblemsHolderImpl extends ArtifactProblemsHolderBase { private void registerProblem(@NotNull String message, @Nullable List> pathToPlace, final ProjectStructureProblemDescription.Severity severity, @NotNull ArtifactProblemQuickFix... quickFixes) { - myProblemsHolder.registerProblem(new ArtifactProblemDescription(message, severity, pathToPlace, Arrays.asList(quickFixes))); + final ArtifactEditorContext context = getContext(); + final Place place = ProjectStructureConfigurable.getInstance(context.getProject()).createArtifactPlace(context.getArtifact()); + myProblemsHolder.registerProblem(new ArtifactProblemDescription(message, severity, pathToPlace, Arrays.asList(quickFixes), place)); } public void registerWarning(@NotNull String message, diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java index 3f95273100f7..1f7b946148da 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java @@ -256,6 +256,12 @@ public class LibraryRootsComponent implements Disposable, LibraryEditorComponent } } + public void updateRootsTree() { + if (myTreeBuilder != null) { + myTreeBuilder.queueUpdate(); + } + } + private class AttachItemAction implements ActionListener { private VirtualFile myLastChosen = null; private final AttachRootButtonDescriptor myDescriptor; @@ -328,7 +334,7 @@ public class LibraryRootsComponent implements Disposable, LibraryEditorComponent } }); updateProperties(); - myTreeBuilder.updateFromRoot(); + myTreeBuilder.queueUpdate(); } return filesToAttach; } @@ -368,7 +374,7 @@ public class LibraryRootsComponent implements Disposable, LibraryEditorComponent protected void librariesChanged(boolean putFocusIntoTree) { updateProperties(); - myTreeBuilder.updateFromRoot(); + myTreeBuilder.queueUpdate(); if (putFocusIntoTree) { myTree.requestFocus(); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibraryConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibraryConfigurable.java index f98a4eed68d0..d3b7fa5e27e2 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibraryConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibraryConfigurable.java @@ -171,4 +171,10 @@ public class LibraryConfigurable extends ProjectStructureElementConfigurable invalidClasses = library.getInvalidRootUrls(OrderRootType.CLASSES); + if (!invalidClasses.isEmpty()) { + final String description = createInvalidRootsDescription(invalidClasses, libraryName); + problemsHolder.registerError(ProjectBundle.message("project.roots.tooltip.library.misconfigured", libraryName), description, createPlace(), + new RemoveInvalidRootsQuickFix(Collections.singletonMap(OrderRootType.CLASSES, invalidClasses), library)); } - else if (!library.allPathsValid(JavadocOrderRootType.getInstance()) || !library.allPathsValid(OrderRootType.SOURCES)) { - problemsHolder.registerWarning(ProjectBundle.message("project.roots.tooltip.library.misconfigured", libraryName)); + final List invalidJavadocs = library.getInvalidRootUrls(JavadocOrderRootType.getInstance()); + final List invalidSources = library.getInvalidRootUrls(OrderRootType.SOURCES); + if (!invalidJavadocs.isEmpty() || !invalidSources.isEmpty()) { + final Map> invalidRoots = new HashMap>(); + invalidRoots.put(OrderRootType.SOURCES, invalidSources); + invalidRoots.put(JavadocOrderRootType.getInstance(), invalidJavadocs); + final String description = createInvalidRootsDescription(ContainerUtil.concat(invalidJavadocs, invalidSources), libraryName); + problemsHolder.registerWarning(ProjectBundle.message("project.roots.tooltip.library.misconfigured", libraryName), description, createPlace(), + new RemoveInvalidRootsQuickFix(invalidRoots, library)); } } + private static String createInvalidRootsDescription(List invalidClasses, String libraryName) { + StringBuilder buffer = new StringBuilder(); + buffer.append(""); + buffer.append("Library '").append(libraryName).append("' has broken paths:"); + for (String url : invalidClasses) { + buffer.append("
  "); + buffer.append(VfsUtil.urlToPath(url)); + } + buffer.append(""); + return buffer.toString(); + } + + @NotNull + private Place createPlace() { + return ProjectStructureConfigurable.getInstance(myContext.getProject()).createProjectOrGlobalLibraryPlace(myLibrary); + } + @Override public List getUsagesInElement() { return Collections.emptyList(); @@ -84,4 +121,39 @@ public class LibraryProjectStructureElement extends ProjectStructureElement { final LibraryTable libraryTable = myLibrary.getTable(); return libraryTable != null && LibraryTablesRegistrar.PROJECT_LEVEL.equals(libraryTable.getTableLevel()); } + + private class RemoveInvalidRootsQuickFix extends ConfigurationErrorQuickFix { + private final Map> myInvalidRoots; + private final Library myLibrary; + + public RemoveInvalidRootsQuickFix(Map> invalidRoots, Library library) { + super("Remove invalid roots"); + myInvalidRoots = invalidRoots; + myLibrary = library; + } + + @Override + public void performFix() { + final LibraryTable.ModifiableModel libraryTable = myContext.getModifiableLibraryTable(myLibrary.getTable()); + if (libraryTable instanceof LibrariesModifiableModel) { + for (OrderRootType rootType : myInvalidRoots.keySet()) { + for (String invalidRoot : myInvalidRoots.get(rootType)) { + final ExistingLibraryEditor libraryEditor = ((LibrariesModifiableModel)libraryTable).getLibraryEditor(myLibrary); + libraryEditor.removeRoot(invalidRoot, rootType); + } + } + myContext.getDaemonAnalyzer().queueUpdate(LibraryProjectStructureElement.this); + final ProjectStructureConfigurable structureConfigurable = ProjectStructureConfigurable.getInstance(myContext.getProject()); + structureConfigurable.navigateTo(createPlace(), true).doWhenDone(new Runnable() { + @Override + public void run() { + final NamedConfigurable configurable = structureConfigurable.getConfigurableFor(myLibrary).getSelectedConfugurable(); + if (configurable instanceof LibraryConfigurable) { + ((LibraryConfigurable)configurable).updateComponent(); + } + } + }); + } + } + } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ModuleProjectStructureElement.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ModuleProjectStructureElement.java index 52832d69a6a8..a457a840cbd5 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ModuleProjectStructureElement.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ModuleProjectStructureElement.java @@ -7,7 +7,9 @@ import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.ui.configuration.ModuleEditor; +import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; +import com.intellij.ui.navigation.Place; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; @@ -39,7 +41,7 @@ public class ModuleProjectStructureElement extends ProjectStructureElement { for (Module each : all) { if (each != myModule && myContext.getRealName(each).equals(myContext.getRealName(myModule))) { - problemsHolder.registerError(ProjectBundle.message("project.roots.module.duplicate.name.message")); + problemsHolder.registerError(ProjectBundle.message("project.roots.module.duplicate.name.message"), null, createPlace(), null); break; } } @@ -50,9 +52,11 @@ public class ModuleProjectStructureElement extends ProjectStructureElement { for (OrderEntry entry : entries) { if (!entry.isValid()){ if (entry instanceof JdkOrderEntry && ((JdkOrderEntry)entry).getJdkName() == null) { - problemsHolder.registerError(ProjectBundle.message("project.roots.module.jdk.problem.message")); + problemsHolder.registerError(ProjectBundle.message("project.roots.module.jdk.problem.message"), null, createPlace(), null); } else { - problemsHolder.registerError(ProjectBundle.message("project.roots.library.problem.message", entry.getPresentableName())); + problemsHolder.registerError(ProjectBundle.message("project.roots.library.problem.message", entry.getPresentableName()), null, + createPlace(), + null); } } //todo[nik] highlight libraries with invalid paths in ClasspathEditor @@ -70,6 +74,10 @@ public class ModuleProjectStructureElement extends ProjectStructureElement { } } + private Place createPlace() { + return ProjectStructureConfigurable.getInstance(myContext.getProject()).createModulePlace(myModule); + } + @Override public List getUsagesInElement() { final List usages = new ArrayList(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblem.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblem.java new file mode 100644 index 000000000000..500b7460a792 --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblem.java @@ -0,0 +1,71 @@ +/* + * Copyright 2000-2010 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.ui.configuration.projectRoot.daemon; + +import com.intellij.openapi.roots.ui.configuration.ConfigurationError; +import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; +import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.ui.popup.PopupStep; +import com.intellij.openapi.ui.popup.util.BaseListPopupStep; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.util.List; + +/** +* @author nik +*/ +class ProjectConfigurationProblem extends ConfigurationError { + private final StructureConfigurableContext myContext; + private final ProjectStructureProblemDescription myDescription; + + public ProjectConfigurationProblem(StructureConfigurableContext context, ProjectStructureProblemDescription description) { + super(description.getMessage(), description.getDescription() != null ? description.getDescription() : description.getMessage()); + myContext = context; + myDescription = description; + } + + @Override + public void navigate() { + ProjectStructureConfigurable.getInstance(myContext.getProject()).navigateTo(myDescription.getPlace(), true); + } + + @Override + public boolean canBeFixed() { + return !myDescription.getFixes().isEmpty(); + } + + @Override + public void fix(JComponent contextComponent) { + final List fixes = myDescription.getFixes(); + if (fixes.size() == 1) { + fixes.get(0).performFix(); + } + else { + JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep(null, fixes) { + @NotNull + @Override + public String getTextFor(ConfigurationErrorQuickFix value) { + return value.getActionName(); + } + + @Override + public PopupStep onChosen(ConfigurationErrorQuickFix selectedValue, boolean finalChoice) { + selectedValue.performFix(); + return FINAL_CHOICE; + } + }).showUnderneathOf(contextComponent); + } + } +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblems.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblems.java index bae70d3391ca..049fe43a80e6 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblems.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblems.java @@ -67,7 +67,7 @@ public class ProjectConfigurationProblems { final List descriptions = problemsHolder.getProblemDescriptions(); if (descriptions != null) { for (ProjectStructureProblemDescription description : descriptions) { - final ProjectConfigurationProblem error = new ProjectConfigurationProblem(description); + final ProjectConfigurationProblem error = new ProjectConfigurationProblem(myContext, description); myErrors.put(element, error); ConfigurationErrors.Bus.addError(error, myContext.getProject()); } @@ -81,18 +81,4 @@ public class ProjectConfigurationProblems { ConfigurationErrors.Bus.removeError(error, myContext.getProject()); } } - - private static class ProjectConfigurationProblem extends ConfigurationError { - public ProjectConfigurationProblem(ProjectStructureProblemDescription description) { - super(description.getMessage(), description.getMessage()); - } - - @Override - public void navigate() { - } - - @Override - public void fix() { - } - } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemDescription.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemDescription.java index 6dd988ad3f19..d4b125dc58fb 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemDescription.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemDescription.java @@ -15,27 +15,51 @@ */ package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon; +import com.intellij.ui.navigation.Place; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; /** * @author nik */ public class ProjectStructureProblemDescription { private final String myMessage; + private final String myDescription; private final Severity mySeverity; + private final Place myPlace; + private final List myFixes; - public ProjectStructureProblemDescription(@NotNull String message, @NotNull Severity severity) { + public ProjectStructureProblemDescription(@NotNull String message, @Nullable String description, @NotNull Severity severity, @NotNull Place place, + @NotNull List fixes) { myMessage = message; + myDescription = description; mySeverity = severity; + myPlace = place; + myFixes = fixes; } public String getMessage() { return myMessage; } + @Nullable + public String getDescription() { + return myDescription; + } + + public List getFixes() { + return myFixes; + } + public Severity getSeverity() { return mySeverity; } + public Place getPlace() { + return myPlace; + } + public enum Severity { ERROR, WARNING } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolder.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolder.java index 9094b4ac654c..411451abfdcc 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolder.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolder.java @@ -15,15 +15,17 @@ */ package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon; +import com.intellij.ui.navigation.Place; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author nik */ public interface ProjectStructureProblemsHolder { - void registerError(@NotNull String message); + void registerError(@NotNull String message, @Nullable String description, @NotNull Place place, @Nullable ConfigurationErrorQuickFix fix); - void registerWarning(@NotNull String message); + void registerWarning(@NotNull String message, @Nullable String description, @NotNull Place place, @Nullable ConfigurationErrorQuickFix fix); void registerProblem(@NotNull ProjectStructureProblemDescription description); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolderImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolderImpl.java index 82cb561b8fd8..ea515d43263f 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolderImpl.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolderImpl.java @@ -1,10 +1,12 @@ package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon; +import com.intellij.ui.navigation.Place; import com.intellij.util.SmartList; import com.intellij.util.StringBuilderSpinAllocator; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collections; import java.util.List; /** @@ -13,12 +15,14 @@ import java.util.List; public class ProjectStructureProblemsHolderImpl implements ProjectStructureProblemsHolder { private List myProblemDescriptions; - public void registerError(@NotNull String message) { - registerProblem(new ProjectStructureProblemDescription(message, ProjectStructureProblemDescription.Severity.ERROR)); + public void registerError(@NotNull String message, String description, @NotNull Place place, @Nullable ConfigurationErrorQuickFix fix) { + final List fixes = fix != null ? Collections.singletonList(fix) : Collections.emptyList(); + registerProblem(new ProjectStructureProblemDescription(message, description, ProjectStructureProblemDescription.Severity.ERROR, place, fixes)); } - public void registerWarning(@NotNull String message) { - registerProblem(new ProjectStructureProblemDescription(message, ProjectStructureProblemDescription.Severity.WARNING)); + public void registerWarning(@NotNull String message, String description, @NotNull Place place, @Nullable ConfigurationErrorQuickFix fix) { + final List fixes = Collections.singletonList(fix); + registerProblem(new ProjectStructureProblemDescription(message, description, ProjectStructureProblemDescription.Severity.WARNING, place, fixes)); } public void registerProblem(final @NotNull ProjectStructureProblemDescription description) { diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryEx.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryEx.java index 839ee0b2b79e..54ac21a3ffd3 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryEx.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryEx.java @@ -22,13 +22,15 @@ import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryProperties; import com.intellij.openapi.roots.libraries.LibraryType; +import java.util.List; + /** * @author dsl */ public interface LibraryEx extends Library { Library cloneLibrary(RootModelImpl rootModel); - boolean allPathsValid(OrderRootType type); + List getInvalidRootUrls(OrderRootType type); boolean isDisposed(); @@ -37,8 +39,6 @@ public interface LibraryEx extends Library { LibraryProperties getProperties(); interface ModifiableModelEx extends ModifiableModel { - boolean allPathsValid(OrderRootType type); - void setProperties(LibraryProperties properties); LibraryProperties getProperties(); diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java index d3e6aa18ffad..5af2d67121e0 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java @@ -39,6 +39,7 @@ import com.intellij.openapi.vfs.pointers.VirtualFilePointerContainer; import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; import com.intellij.util.ArrayUtil; import com.intellij.util.ReflectionUtil; +import com.intellij.util.SmartList; import com.intellij.util.containers.HashMap; import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters; @@ -204,14 +205,18 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { return clone; } - public boolean allPathsValid(OrderRootType type) { + public List getInvalidRootUrls(OrderRootType type) { final List pointers = myRoots.get(type).getList(); + List invalidPaths = null; for (VirtualFilePointer pointer : pointers) { if (!pointer.isValid()) { - return false; + if (invalidPaths == null) { + invalidPaths = new SmartList(); + } + invalidPaths.add(pointer.getUrl()); } } - return true; + return invalidPaths != null ? invalidPaths : Collections.emptyList(); } @Override From a65019d5de4e96a5225aff394f327525734fc8e6 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Tue, 9 Nov 2010 11:27:40 +0300 Subject: [PATCH 029/257] IDEA-60781 After formatting cursor jumps from indented position to beginning of the line. Restricted caret position restoring only for the use-cases when caret is located at the line that contains only white spaces --- .../codeStyle/CodeStyleManagerImpl.java | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java index 4e4d1813e0f6..e3db5036e4cb 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java @@ -146,6 +146,32 @@ public class CodeStyleManagerImpl extends CodeStyleManager { LOG.error("end=" + start + "; end=" + file); } + Editor editor = PsiUtilBase.findEditor(file); + + // There is a possible case that cursor is located at the end of the line that contains only white spaces. For example: + // public void foo() { + // + // } + // Formatter removes such white spaces, i.e. keeps only line feed symbol. But we want to preserve caret position then. + // So, we check if it should be preserved and restore it after formatting if necessary + boolean fixCaretPosition = false; + if (editor != null) { + int caretOffset = editor.getCaretModel().getOffset(); + Document document = editor.getDocument(); + CharSequence text = document.getCharsSequence(); + int caretLine = document.getLineNumber(Math.max(Math.min(caretOffset, document.getTextLength() - 1), 0)); + int lineStartOffset = document.getLineStartOffset(caretLine); + fixCaretPosition = true; + for (int i = caretOffset; i>= lineStartOffset; i--) { + char c = text.charAt(i); + if (c != ' ' && c != '\t' && c != '\n') { + fixCaretPosition = false; + break; + } + } + } + + boolean formatFromStart = startOffset == 0; boolean formatToEnd = endOffset == file.getTextLength(); @@ -163,25 +189,23 @@ public class CodeStyleManagerImpl extends CodeStyleManager { formatToEnd ? file.getTextLength() : endElement.getTextRange().getEndOffset())); } - Editor editor = PsiUtilBase.findEditor(file); - if (editor == null) { + if (!fixCaretPosition) { return; } - CaretModel caretModel = editor.getCaretModel(); String indent = getLineIndent(file, caretModel.getOffset()); if (indent == null) { return; } int tabSize = getSettings().getTabSize(file.getFileType()); - int indentColumn = indentWithInVisualColumns(indent, tabSize); + int indentColumn = indentInVisualColumns(indent, tabSize); VisualPosition position = caretModel.getVisualPosition(); if (indentColumn != position.column) { caretModel.moveToVisualPosition(new VisualPosition(position.line, indentColumn)); } } - private static int indentWithInVisualColumns(String indent, int tabSize) { + private static int indentInVisualColumns(String indent, int tabSize) { if (tabSize <= 1) { return indent.length(); } From 851329b79e7ebb0a95044c2d5a8f870b454735ee Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 9 Nov 2010 11:32:42 +0300 Subject: [PATCH 030/257] xdebugger api: support for multiline error messages and error messages with hyperlinks --- .../xdebugger/frame/XCompositeNode.java | 8 ++++ .../frame/XDebuggerTreeNodeHyperlink.java} | 11 +++-- .../xdebugger/impl/ui/tree/XDebuggerTree.java | 5 ++- .../impl/ui/tree/XDebuggerTreeRenderer.java | 4 +- .../impl/ui/tree/nodes/MessageTreeNode.java | 45 ++++++++++++------- .../impl/ui/tree/nodes/XDebuggerTreeNode.java | 3 +- .../ui/tree/nodes/XValueContainerNode.java | 14 +++++- .../impl/ui/tree/nodes/XValueNodeImpl.java | 9 ++-- 8 files changed, 68 insertions(+), 31 deletions(-) rename platform/{xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerNodeLink.java => xdebugger-api/src/com/intellij/xdebugger/frame/XDebuggerTreeNodeHyperlink.java} (76%) diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XCompositeNode.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XCompositeNode.java index badc500ae727..b2a550d36647 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XCompositeNode.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XCompositeNode.java @@ -17,6 +17,7 @@ package com.intellij.xdebugger.frame; import com.intellij.xdebugger.Obsolescent; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -47,4 +48,11 @@ public interface XCompositeNode extends Obsolescent { * @param errorMessage message describing the error */ void setErrorMessage(@NotNull String errorMessage); + + /** + * Indicates that an error occurs + * @param errorMessage message describing the error + * @param link describes a hyperlink which will be appended to the error message + */ + void setErrorMessage(@NotNull String errorMessage, @Nullable XDebuggerTreeNodeHyperlink link); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerNodeLink.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XDebuggerTreeNodeHyperlink.java similarity index 76% rename from platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerNodeLink.java rename to platform/xdebugger-api/src/com/intellij/xdebugger/frame/XDebuggerTreeNodeHyperlink.java index ea93a8ad7b99..b7689ae65d5f 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerNodeLink.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XDebuggerTreeNodeHyperlink.java @@ -13,20 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.xdebugger.impl.ui.tree.nodes; +package com.intellij.xdebugger.frame; + +import org.jetbrains.annotations.NotNull; import java.awt.event.MouseEvent; /** + * Describes a hyperlink inside a debugger node + * * @author nik */ -public abstract class XDebuggerNodeLink { +public abstract class XDebuggerTreeNodeHyperlink { private String myLinkText; - protected XDebuggerNodeLink(String linkText) { + protected XDebuggerTreeNodeHyperlink(@NotNull String linkText) { myLinkText = linkText; } + @NotNull public String getLinkText() { return myLinkText; } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java index d002d1f2da1a..425aec3cb0a2 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java @@ -28,6 +28,7 @@ import com.intellij.util.containers.Convertor; import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; +import com.intellij.xdebugger.frame.XDebuggerTreeNodeHyperlink; import com.intellij.xdebugger.impl.ui.tree.nodes.*; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -78,8 +79,8 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider { new TreeLinkMouseListener(new XDebuggerTreeRenderer()) { @Override protected void handleTagClick(Object tag, MouseEvent event) { - if (tag instanceof XDebuggerNodeLink) { - ((XDebuggerNodeLink)tag).onClick(event); + if (tag instanceof XDebuggerTreeNodeHyperlink) { + ((XDebuggerTreeNodeHyperlink)tag).onClick(event); } } }.install(this); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTreeRenderer.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTreeRenderer.java index 06f901c7f4c7..a7a20094c15c 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTreeRenderer.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTreeRenderer.java @@ -17,7 +17,7 @@ package com.intellij.xdebugger.impl.ui.tree; import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.SimpleTextAttributes; -import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerNodeLink; +import com.intellij.xdebugger.frame.XDebuggerTreeNodeHyperlink; import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode; import javax.swing.*; @@ -35,7 +35,7 @@ class XDebuggerTreeRenderer extends ColoredTreeCellRenderer { final boolean hasFocus) { XDebuggerTreeNode node = (XDebuggerTreeNode)value; node.getText().appendToComponent(this); - final XDebuggerNodeLink link = node.getLink(); + final XDebuggerTreeNodeHyperlink link = node.getLink(); if (link != null) { append(link.getLinkText(), SimpleTextAttributes.LINK_ATTRIBUTES, link); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/MessageTreeNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/MessageTreeNode.java index e3c70553dcb4..ec47fecf023d 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/MessageTreeNode.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/MessageTreeNode.java @@ -15,8 +15,11 @@ */ package com.intellij.xdebugger.impl.ui.tree.nodes; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.SimpleTextAttributes; +import com.intellij.util.ui.EmptyIcon; import com.intellij.xdebugger.XDebuggerBundle; +import com.intellij.xdebugger.frame.XDebuggerTreeNodeHyperlink; import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants; import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree; import org.jetbrains.annotations.NotNull; @@ -24,6 +27,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.tree.TreeNode; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -31,17 +35,25 @@ import java.util.List; * @author nik */ public class MessageTreeNode extends XDebuggerTreeNode { + private static final EmptyIcon EMPTY_ICON = new EmptyIcon(XDebuggerUIConstants.ERROR_MESSAGE_ICON); private boolean myEllipsis; + private XDebuggerTreeNodeHyperlink myLink; private MessageTreeNode(XDebuggerTree tree, final XDebuggerTreeNode parent, final String message, final SimpleTextAttributes attributes, @Nullable Icon icon) { - this(tree, parent, message, attributes, icon, false); + this(tree, parent, message, attributes, icon, null); } - private MessageTreeNode(XDebuggerTree tree, final XDebuggerTreeNode parent, final String message, final SimpleTextAttributes attributes, @Nullable Icon icon, - final boolean ellipsis) { + private MessageTreeNode(XDebuggerTree tree, final XDebuggerTreeNode parent, final String message, final SimpleTextAttributes attributes, + @Nullable Icon icon, final XDebuggerTreeNodeHyperlink link) { + this(tree, parent, message, attributes, icon, false, link); + } + + private MessageTreeNode(XDebuggerTree tree, final XDebuggerTreeNode parent, final String message, final SimpleTextAttributes attributes, + @Nullable Icon icon, final boolean ellipsis, final XDebuggerTreeNodeHyperlink link) { super(tree, parent, true); myEllipsis = ellipsis; + myLink = link; setIcon(icon); myText.append(message, attributes); } @@ -51,11 +63,6 @@ public class MessageTreeNode extends XDebuggerTreeNode { myEllipsis = false; } - private MessageTreeNode(XDebuggerTree tree, XDebuggerTreeNode parent, String infoMessage, String errorMessage) { - super(tree, parent, true); - myEllipsis = false; - } - protected List getChildren() { return Collections.emptyList(); } @@ -64,6 +71,11 @@ public class MessageTreeNode extends XDebuggerTreeNode { return myEllipsis; } + @Override + public XDebuggerTreeNodeHyperlink getLink() { + return myLink; + } + public List getLoadedChildren() { return null; } @@ -74,7 +86,7 @@ public class MessageTreeNode extends XDebuggerTreeNode { public static MessageTreeNode createEllipsisNode(XDebuggerTree tree, XDebuggerTreeNode parent, final int remaining) { String message = remaining == -1 ? "..." : XDebuggerBundle.message("node.text.ellipsis.0.more.nodes.double.click.to.show", remaining); - return new MessageTreeNode(tree, parent, message, SimpleTextAttributes.REGULAR_ATTRIBUTES, null, true); + return new MessageTreeNode(tree, parent, message, SimpleTextAttributes.REGULAR_ATTRIBUTES, null, true, null); } public static MessageTreeNode createMessageNode(XDebuggerTree tree, XDebuggerTreeNode parent, String message, @Nullable Icon icon) { @@ -85,16 +97,19 @@ public class MessageTreeNode extends XDebuggerTreeNode { return new MessageTreeNode(tree, parent, XDebuggerUIConstants.COLLECTING_DATA_MESSAGE, XDebuggerUIConstants.COLLECTING_DATA_HIGHLIGHT_ATTRIBUTES, null); } - public static MessageTreeNode createEvaluatingMessage(XDebuggerTree tree, final XDebuggerTreeNode parent, final String message) { - return new MessageTreeNode(tree, parent, message, XDebuggerUIConstants.EVALUATING_EXPRESSION_HIGHLIGHT_ATTRIBUTES, null); - } - public static MessageTreeNode createEvaluatingMessage(XDebuggerTree tree, final XDebuggerTreeNode parent) { return new MessageTreeNode(tree, parent, XDebuggerUIConstants.EVALUATING_EXPRESSION_MESSAGE, XDebuggerUIConstants.EVALUATING_EXPRESSION_HIGHLIGHT_ATTRIBUTES, null); } - public static MessageTreeNode createErrorMessage(XDebuggerTree tree, final XDebuggerTreeNode parent, @NotNull String errorMessage) { - return new MessageTreeNode(tree, parent, errorMessage, XDebuggerUIConstants.ERROR_MESSAGE_ATTRIBUTES, XDebuggerUIConstants.ERROR_MESSAGE_ICON); + public static List createErrorMessages(XDebuggerTree tree, final XDebuggerTreeNode parent, @NotNull String errorMessage, + XDebuggerTreeNodeHyperlink link) { + List messages = new ArrayList(1); + final List lines = StringUtil.split(errorMessage, "\n"); + for (int i = 0; i < lines.size(); i++) { + final Icon icon = i == 0 ? XDebuggerUIConstants.ERROR_MESSAGE_ICON : EMPTY_ICON; + messages.add(new MessageTreeNode(tree, parent, lines.get(i), XDebuggerUIConstants.ERROR_MESSAGE_ATTRIBUTES, icon, i == 0 ? link : null)); + } + return messages; } public static MessageTreeNode createInfoMessage(XDebuggerTree tree, final XDebuggerTreeNode parent, @NotNull String message) { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java index 78019ab2d30d..31985506f5a6 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java @@ -17,6 +17,7 @@ package com.intellij.xdebugger.impl.ui.tree.nodes; import com.intellij.ui.SimpleColoredText; import com.intellij.util.enumeration.EmptyEnumeration; +import com.intellij.xdebugger.frame.XDebuggerTreeNodeHyperlink; import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -87,7 +88,7 @@ public abstract class XDebuggerTreeNode implements TreeNode { } @Nullable - public XDebuggerNodeLink getLink() { + public XDebuggerTreeNodeHyperlink getLink() { return null; } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java index 03fa75102232..2faa7711094d 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java @@ -16,6 +16,7 @@ package com.intellij.xdebugger.impl.ui.tree.nodes; import com.intellij.xdebugger.frame.XCompositeNode; +import com.intellij.xdebugger.frame.XDebuggerTreeNodeHyperlink; import com.intellij.xdebugger.frame.XValue; import com.intellij.xdebugger.frame.XValueContainer; import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; @@ -110,20 +111,29 @@ public abstract class XValueContainerNode messages) { myCachedAllChildren = null; final int[] indices = getNodesIndices(myMessageChildren); final TreeNode[] nodes = getChildNodes(indices); myMessageChildren = Collections.emptyList(); fireNodesRemoved(indices, nodes); - myMessageChildren = Collections.singletonList(messageNode); + myMessageChildren = messages; myCachedAllChildren = null; fireNodesInserted(myMessageChildren); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java index 7a85c146fb19..1aa1934598e6 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java @@ -19,10 +19,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.SimpleTextAttributes; import com.intellij.util.StringBuilderSpinAllocator; -import com.intellij.xdebugger.frame.XCompositeNode; -import com.intellij.xdebugger.frame.XFullValueEvaluator; -import com.intellij.xdebugger.frame.XValue; -import com.intellij.xdebugger.frame.XValueNode; +import com.intellij.xdebugger.frame.*; import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants; import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree; @@ -117,9 +114,9 @@ public class XValueNodeImpl extends XValueContainerNode implements XValu @Override - public XDebuggerNodeLink getLink() { + public XDebuggerTreeNodeHyperlink getLink() { if (myFullValueEvaluator != null) { - return new XDebuggerNodeLink(myFullValueEvaluator.getLinkText()) { + return new XDebuggerTreeNodeHyperlink(myFullValueEvaluator.getLinkText()) { @Override public void onClick(MouseEvent event) { DebuggerUIUtil.showValuePopup(myFullValueEvaluator, event, myTree.getProject()); From 21b2c5a6f1df3ba87f9f003f0b111e23513fecbf Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Mon, 8 Nov 2010 20:07:51 +0300 Subject: [PATCH 031/257] assertion added --- .../compiler/impl/javaCompiler/BackendCompilerWrapper.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java index a9506978cd6e..cb32e9ed21a8 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java @@ -723,9 +723,11 @@ public class BackendCompilerWrapper { final String realOutputDir; if (myCompileContext.isInTestSourceContent(sourceFile)) { realOutputDir = getTestsOutputDir(module); + LOG.assertTrue(realOutputDir != null); } else { realOutputDir = getOutputDir(module); + LOG.assertTrue(realOutputDir != null); } if (FileUtil.pathsEqual(tempOutputDir, realOutputDir)) { // no need to move From 984bfb74856217689bc0f7f12ebf33507195a78b Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Mon, 8 Nov 2010 23:24:18 +0300 Subject: [PATCH 032/257] fix assertion "Semaphore for unsaved data indexing was not initialized for index" --- .../util/indexing/FileBasedIndex.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java index 0e93450ad8f4..a06c532ebe92 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java @@ -604,9 +604,12 @@ public class FileBasedIndex implements ApplicationComponent { */ public boolean processAllKeys(final ID indexId, Processor processor, @Nullable Project project) { try { - ensureUpToDate(indexId, project, project != null? GlobalSearchScope.allScope(project) : new EverythingGlobalScope()); final UpdatableIndex index = getIndex(indexId); - return index == null || index.processAllKeys(processor); + if (index == null) { + return true; + } + ensureUpToDate(indexId, project, project != null? GlobalSearchScope.allScope(project) : new EverythingGlobalScope()); + return index.processAllKeys(processor); } catch (StorageException e) { scheduleRebuild(indexId, e); @@ -779,13 +782,13 @@ public class FileBasedIndex implements ApplicationComponent { @Nullable final VirtualFile restrictToFile, ValueProcessor processor, final GlobalSearchScope filter) { try { - final Project project = filter.getProject(); - //assert project != null : "GlobalSearchScope#getProject() should be not-null for all index queries"; - ensureUpToDate(indexId, project, filter); final UpdatableIndex index = getIndex(indexId); if (index == null) { return true; } + final Project project = filter.getProject(); + //assert project != null : "GlobalSearchScope#getProject() should be not-null for all index queries"; + ensureUpToDate(indexId, project, filter); final Lock readLock = index.getReadLock(); try { @@ -850,13 +853,13 @@ public class FileBasedIndex implements ApplicationComponent { public boolean getFilesWithKey(final ID indexId, final Set dataKeys, Processor processor, GlobalSearchScope filter) { try { - final Project project = filter.getProject(); - //assert project != null : "GlobalSearchScope#getProject() should be not-null for all index queries"; - ensureUpToDate(indexId, project, filter); final UpdatableIndex index = getIndex(indexId); if (index == null) { return true; } + final Project project = filter.getProject(); + //assert project != null : "GlobalSearchScope#getProject() should be not-null for all index queries"; + ensureUpToDate(indexId, project, filter); final Lock readLock = index.getReadLock(); try { From 4f5f9f485a39968171c5caa52ca8030c10fbf638 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 8 Nov 2010 18:08:17 +0300 Subject: [PATCH 033/257] preserve highlights on enter --- .../daemonCodeAnalyzer/lossyEncoding/Text.txt | 2 +- .../codeInsight/daemon/LossyEncodingTest.java | 5 ++-- .../codeInsight/CodeInsightTestCase.java | 23 ++++++++++++++++--- .../daemon/impl/UpdateHighlightersUtil.java | 6 ++--- .../com/intellij/openapi/util/TextRange.java | 5 +++- 5 files changed, 30 insertions(+), 11 deletions(-) diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lossyEncoding/Text.txt b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lossyEncoding/Text.txt index acbe86c7c895..8f7b7c24f052 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lossyEncoding/Text.txt +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lossyEncoding/Text.txt @@ -1 +1 @@ -abcd +abcd diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LossyEncodingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LossyEncodingTest.java index 1c96e84bf3fd..6f7f21d5cc36 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LossyEncodingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LossyEncodingTest.java @@ -36,8 +36,7 @@ public class LossyEncodingTest extends LightDaemonAnalyzerTestCase { int end = myEditor.getCaretModel().getOffset(); Collection infos = doHighlighting(); - assertEquals(1, infos.size()); - HighlightInfo info = infos.iterator().next(); + HighlightInfo info = assertOneElement(infos); assertEquals("Unsupported characters for the charset 'US-ASCII'", info.description); assertEquals(start, info.startOffset); assertEquals(end, info.endOffset); @@ -92,4 +91,4 @@ public class LossyEncodingTest extends LightDaemonAnalyzerTestCase { private void doTest(@NonNls String filePath) throws Exception { doTest(BASE_PATH + "/" + filePath, true, false); } -} \ No newline at end of file +} diff --git a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java index e69bad860077..b2d25802d9d5 100644 --- a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java +++ b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java @@ -623,9 +623,18 @@ public abstract class CodeInsightTestCase extends PsiTestCase { } protected void type(char c) { + type(c, getEditor()); + } + + protected static void type(char c, Editor editor) { EditorActionManager actionManager = EditorActionManager.getInstance(); + DataContext dataContext = DataManager.getInstance().getDataContext(); + if (c == '\n') { + actionManager.getActionHandler(IdeActions.ACTION_EDITOR_ENTER).execute(editor, dataContext); + return; + } TypedAction action = actionManager.getTypedAction(); - action.actionPerformed(getEditor(), c, DataManager.getInstance().getDataContext()); + action.actionPerformed(editor, c, dataContext); } protected void caretRight() { @@ -633,6 +642,11 @@ public abstract class CodeInsightTestCase extends PsiTestCase { EditorActionHandler action = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT); action.execute(getEditor(), DataManager.getInstance().getDataContext()); } + protected void deleteLine() { + EditorActionManager actionManager = EditorActionManager.getInstance(); + EditorActionHandler action = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_DELETE_LINE); + action.execute(getEditor(), DataManager.getInstance().getDataContext()); + } protected void type(@NonNls String s) { for (char c : s.toCharArray()) { @@ -647,15 +661,18 @@ public abstract class CodeInsightTestCase extends PsiTestCase { } protected void backspace() { + backspace(getEditor()); + } + protected void backspace(final Editor editor) { CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() { @Override public void run() { EditorActionManager actionManager = EditorActionManager.getInstance(); EditorActionHandler actionHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_BACKSPACE); - actionHandler.execute(getEditor(), DataManager.getInstance().getDataContext()); + actionHandler.execute(editor, DataManager.getInstance().getDataContext()); } - }, "backspace", getEditor().getDocument()); + }, "backspace", editor.getDocument()); } protected void ctrlShiftF7() { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/UpdateHighlightersUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/UpdateHighlightersUtil.java index 00a3dd6d9342..48f71b088b5f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/UpdateHighlightersUtil.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/UpdateHighlightersUtil.java @@ -163,7 +163,7 @@ public class UpdateHighlightersUtil { int startOffset, int endOffset, @NotNull final HighlightInfo info, - @Nullable final EditorColorsScheme colorsScheme, // if null global scheme will be used + @Nullable final EditorColorsScheme colorsScheme, // if null global scheme will be used final int group) { ApplicationManager.getApplication().assertIsDispatchThread(); if (info.isFileLevelAnnotation || info.getGutterIconRenderer() != null) return; @@ -313,10 +313,10 @@ public class UpdateHighlightersUtil { public boolean process(HighlightInfo info) { if (info.group == group) { RangeHighlighter highlighter = info.highlighter; - int hiEnd = highlighter.getEndOffset(); int hiStart = highlighter.getStartOffset(); + int hiEnd = highlighter.getEndOffset(); boolean willBeRemoved = hiEnd == document.getTextLength() && range.getEndOffset() == document.getTextLength() - || range.intersects(hiStart, hiEnd); + || range.intersectsStrict(hiStart, hiEnd) || range.containsRange(hiStart, hiEnd) || hiStart <= range.getStartOffset() && hiEnd >= range.getEndOffset(); if (willBeRemoved) { infosToRemove.recycleHighlighter(highlighter); info.highlighter = null; diff --git a/platform/util/src/com/intellij/openapi/util/TextRange.java b/platform/util/src/com/intellij/openapi/util/TextRange.java index 3fd084e3269a..83af33e86d94 100644 --- a/platform/util/src/com/intellij/openapi/util/TextRange.java +++ b/platform/util/src/com/intellij/openapi/util/TextRange.java @@ -112,7 +112,10 @@ public class TextRange { return Math.max(myStartOffset, startOffset) <= Math.min(myEndOffset, endOffset); } public boolean intersectsStrict(@NotNull TextRange textRange) { - return Math.max(myStartOffset, textRange.getStartOffset()) < Math.min(myEndOffset, textRange.getEndOffset()); + return intersectsStrict(textRange.getStartOffset(), textRange.getEndOffset()); + } + public boolean intersectsStrict(int startOffset, int endOffset) { + return Math.max(myStartOffset, startOffset) < Math.min(myEndOffset, endOffset); } @Nullable From 1587f043a132c784349ff0355b89ae2a54c5f707 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Tue, 9 Nov 2010 13:08:16 +0300 Subject: [PATCH 034/257] reentrance problem with focus manager fixed --- .../com/intellij/openapi/wm/impl/FocusManagerImpl.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java index 5213d21c9778..3b13417c3c25 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java @@ -348,6 +348,10 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { UIUtil.invokeLaterIfNeeded(new Runnable() { @Override public void run() { + if (isFlushingIdleRequests()) { + SwingUtilities.invokeLater(this); + } + if (myRunContext != null) { runnable.run(); return; @@ -479,7 +483,7 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { public boolean dispatch(KeyEvent e) { if (!Registry.is("actionSystem.fixLostTyping")) return false; - if (myFlushingIdleRequestsEntryCount > 0) return false; + if (isFlushingIdleRequests()) return false; if (!isFocusTransferReady() || !isPendingKeyEventsRedispatched()) { for (FocusCommand each : myFocusRequests) { @@ -502,6 +506,10 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { } } + private boolean isFlushingIdleRequests() { + return myFlushingIdleRequestsEntryCount > 0; + } + public void suspendKeyProcessingUntil(@NotNull final ActionCallback done) { requestFocus(new FocusCommand(done) { public ActionCallback run() { From d26176923cafbfec362af4849b155ccb9bb64d70 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 9 Nov 2010 12:54:57 +0300 Subject: [PATCH 035/257] Named scope for Project files --- .../psi/search/scope/ProjectFilesScope.java | 43 +++++++++++++++++++ .../DefaultScopesProvider.java | 10 ++--- 2 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 platform/lang-api/src/com/intellij/psi/search/scope/ProjectFilesScope.java diff --git a/platform/lang-api/src/com/intellij/psi/search/scope/ProjectFilesScope.java b/platform/lang-api/src/com/intellij/psi/search/scope/ProjectFilesScope.java new file mode 100644 index 000000000000..f989d8972b94 --- /dev/null +++ b/platform/lang-api/src/com/intellij/psi/search/scope/ProjectFilesScope.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.search.scope; + +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.search.scope.packageSet.AbstractPackageSet; +import com.intellij.psi.search.scope.packageSet.NamedScope; +import com.intellij.psi.search.scope.packageSet.NamedScopesHolder; + +/** + * @author Konstantin Bulenkov + */ +public class ProjectFilesScope extends NamedScope { + public static final String NAME = "Project Files"; + public ProjectFilesScope() { + super(NAME, new AbstractPackageSet("ProjectFiles") { + public boolean contains(PsiFile psiFile, NamedScopesHolder holder) { + final VirtualFile file = psiFile.getVirtualFile(); + if (file == null) return false; + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(holder.getProject()).getFileIndex(); + return holder.getProject().isInitialized() + && !fileIndex.isIgnored(file) + && fileIndex.getContentRootForFile(file) != null; + } + }); + } +} diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/DefaultScopesProvider.java b/platform/lang-impl/src/com/intellij/packageDependencies/DefaultScopesProvider.java index 7a988428c46f..c18aed8e50af 100644 --- a/platform/lang-impl/src/com/intellij/packageDependencies/DefaultScopesProvider.java +++ b/platform/lang-impl/src/com/intellij/packageDependencies/DefaultScopesProvider.java @@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project; import com.intellij.problems.WolfTheProblemSolver; import com.intellij.psi.PsiFile; import com.intellij.psi.search.scope.NonProjectFilesScope; +import com.intellij.psi.search.scope.ProjectFilesScope; import com.intellij.psi.search.scope.TestsScope; import com.intellij.psi.search.scope.packageSet.*; import org.jetbrains.annotations.NotNull; @@ -35,8 +36,6 @@ import java.util.List; * @author Konstantin Bulenkov */ public class DefaultScopesProvider implements CustomScopesProvider { - private final NamedScope myProjectTestScope; - private final NamedScope myNonProjectScope; private final NamedScope myProblemsScope; private final Project myProject; private final List myScopes; @@ -47,8 +46,9 @@ public class DefaultScopesProvider implements CustomScopesProvider { public DefaultScopesProvider(Project project) { myProject = project; - myProjectTestScope = new TestsScope(); - myNonProjectScope = new NonProjectFilesScope(); + final NamedScope projectScope = new ProjectFilesScope(); + final NamedScope projectTestScope = new TestsScope(); + final NamedScope nonProjectScope = new NonProjectFilesScope(); final String text = FilePatternPackageSet.SCOPE_FILE + ":*//*"; myProblemsScope = new NamedScope(IdeBundle.message("predefined.scope.problems.name"), new AbstractPackageSet(text) { public boolean contains(PsiFile file, NamedScopesHolder holder) { @@ -56,7 +56,7 @@ public class DefaultScopesProvider implements CustomScopesProvider { && WolfTheProblemSolver.getInstance(myProject).isProblemFile(file.getVirtualFile()); } }); - myScopes = Arrays.asList(getProblemsScope(), getAllScope(), myProjectTestScope, myNonProjectScope); + myScopes = Arrays.asList(projectScope, getProblemsScope(), getAllScope(), projectTestScope, nonProjectScope); } @NotNull From b7bfb1a8789e110b9135ac71ebc34c382ba77b75 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 9 Nov 2010 13:18:38 +0300 Subject: [PATCH 036/257] prepopulate choose by name with selected text in editor (IDEA-57250) --- .../src/com/intellij/ide/actions/GotoActionBase.java | 11 +++++++++++ .../src/com/intellij/ide/actions/GotoClassAction.java | 3 ++- .../src/com/intellij/ide/actions/GotoFileAction.java | 3 ++- .../com/intellij/ide/actions/GotoSymbolAction.java | 3 ++- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/actions/GotoActionBase.java b/platform/lang-impl/src/com/intellij/ide/actions/GotoActionBase.java index 0fda5957f06e..4c69b3a20065 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/GotoActionBase.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/GotoActionBase.java @@ -34,6 +34,17 @@ public abstract class GotoActionBase extends AnAction { protected static Class myInAction = null; + public static String getInitialText(Editor editor) { + if (editor == null) { + return ""; + } + final String selectedText = editor.getSelectionModel().getSelectedText(); + if (selectedText != null && selectedText.indexOf("\n") < 0) { + return selectedText; + } + return ""; + } + public final void actionPerformed(AnActionEvent e) { LOG.assertTrue (!getClass ().equals (myInAction)); try { diff --git a/platform/lang-impl/src/com/intellij/ide/actions/GotoClassAction.java b/platform/lang-impl/src/com/intellij/ide/actions/GotoClassAction.java index 6842dec2b59f..7dd49cbbf3c5 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/GotoClassAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/GotoClassAction.java @@ -47,7 +47,8 @@ public class GotoClassAction extends GotoActionBase implements DumbAware { PsiDocumentManager.getInstance(project).commitAllDocuments(); final GotoClassModel2 model = new GotoClassModel2(project); - final ChooseByNamePopup popup = ChooseByNamePopup.createPopup(project, model, getPsiContext(e)); + final ChooseByNamePopup popup = ChooseByNamePopup.createPopup(project, model, getPsiContext(e), + getInitialText(e.getData(PlatformDataKeys.EDITOR))); final ChooseByNameFilter filterUI = new ChooseByNameLanguageFilter(popup, model, GotoClassSymbolConfiguration.getInstance(project), project); popup.invoke(new ChooseByNamePopupComponent.Callback() { diff --git a/platform/lang-impl/src/com/intellij/ide/actions/GotoFileAction.java b/platform/lang-impl/src/com/intellij/ide/actions/GotoFileAction.java index a1c64f86dcc4..823b1e8a7b72 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/GotoFileAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/GotoFileAction.java @@ -52,7 +52,8 @@ public class GotoFileAction extends GotoActionBase implements DumbAware { FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.popup.file"); final Project project = e.getData(PlatformDataKeys.PROJECT); final GotoFileModel gotoFileModel = new GotoFileModel(project); - final ChooseByNamePopup popup = ChooseByNamePopup.createPopup(project, gotoFileModel, getPsiContext(e)); + final ChooseByNamePopup popup = ChooseByNamePopup.createPopup(project, gotoFileModel, getPsiContext(e), + getInitialText(e.getData(PlatformDataKeys.EDITOR))); final ChooseByNameFilter filterUI = new GotoFileFilter(popup, gotoFileModel, project); popup.invoke(new ChooseByNamePopupComponent.Callback() { public void onClose() { diff --git a/platform/lang-impl/src/com/intellij/ide/actions/GotoSymbolAction.java b/platform/lang-impl/src/com/intellij/ide/actions/GotoSymbolAction.java index 26a68ae23cb3..ef2d7197d441 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/GotoSymbolAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/GotoSymbolAction.java @@ -36,7 +36,8 @@ public class GotoSymbolAction extends GotoActionBase { PsiDocumentManager.getInstance(project).commitAllDocuments(); final GotoSymbolModel2 model = new GotoSymbolModel2(project); - final ChooseByNamePopup popup = ChooseByNamePopup.createPopup(project, model, getPsiContext(e)); + final ChooseByNamePopup popup = ChooseByNamePopup.createPopup(project, model, getPsiContext(e), + getInitialText(e.getData(PlatformDataKeys.EDITOR))); final ChooseByNameFilter filterUI = new ChooseByNameLanguageFilter(popup, model, GotoClassSymbolConfiguration.getInstance(project), project); popup.invoke(new ChooseByNamePopupComponent.Callback() { From 5a2c1d2ab47b494e7f0cce7c0b959015542edc01 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 9 Nov 2010 13:23:33 +0300 Subject: [PATCH 037/257] Import settings dialog: don't gray out deselected items (IDEA-60940) --- .../com/intellij/ide/actions/ChooseComponentsToExportDialog.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ChooseComponentsToExportDialog.java b/platform/platform-impl/src/com/intellij/ide/actions/ChooseComponentsToExportDialog.java index cb6e09877419..7874189358ca 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ChooseComponentsToExportDialog.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ChooseComponentsToExportDialog.java @@ -68,6 +68,7 @@ public class ChooseComponentsToExportDialog extends DialogWrapper { } final Set componentElementProperties = new LinkedHashSet(componentToContainingListElement.values()); myChooser = new ElementsChooser(true); + myChooser.setColorUnmarkedElements(false); for (final ComponentElementProperties componentElementProperty : componentElementProperties) { myChooser.addElement(componentElementProperty, true, componentElementProperty); } From e5cca9cde569f364c632a5f534576ee5c7ae7461 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 9 Nov 2010 13:46:33 +0300 Subject: [PATCH 038/257] provide "delete to line end" action, use it in Eclipse keymap (IDEA-56243) --- .../editor/actions/CutLineEndAction.java | 14 +++++++--- .../editor/actions/DeleteToLineEndAction.java | 27 +++++++++++++++++++ .../src/idea/Keymap_Eclipse.xml | 2 +- .../src/idea/PlatformActions.xml | 1 + 4 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 platform/platform-impl/src/com/intellij/openapi/editor/actions/DeleteToLineEndAction.java diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/CutLineEndAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/CutLineEndAction.java index d42ec92ad09f..154423330c7c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/CutLineEndAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/CutLineEndAction.java @@ -40,10 +40,16 @@ import java.awt.datatransfer.StringSelection; public class CutLineEndAction extends EditorAction { public CutLineEndAction() { - super(new Handler()); + super(new Handler(true)); } - private static class Handler extends EditorWriteActionHandler { + static class Handler extends EditorWriteActionHandler { + private final boolean myCopyToClipboard; + + Handler(boolean copyToClipboard) { + myCopyToClipboard = copyToClipboard; + } + public void executeWriteAction(Editor editor, DataContext dataContext) { final Document doc = editor.getDocument(); if (doc.getLineCount() == 0) return; @@ -56,7 +62,9 @@ public class CutLineEndAction extends EditorAction { return; } - copyToClipboard(doc, caretOffset, lineEndOffset, dataContext, editor); + if (myCopyToClipboard) { + copyToClipboard(doc, caretOffset, lineEndOffset, dataContext, editor); + } final int lineStartOffset = doc.getLineStartOffset(lineNumber); if (StringUtil.isEmptyOrSpaces(doc.getCharsSequence().subSequence(lineStartOffset, lineEndOffset).toString())) { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/DeleteToLineEndAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/DeleteToLineEndAction.java new file mode 100644 index 000000000000..b178ba89728c --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/DeleteToLineEndAction.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2010 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.editor.actions; + +import com.intellij.openapi.editor.actionSystem.EditorAction; + +/** + * @author yole + */ +public class DeleteToLineEndAction extends EditorAction { + public DeleteToLineEndAction() { + super(new CutLineEndAction.Handler(false)); + } +} diff --git a/platform/platform-resources/src/idea/Keymap_Eclipse.xml b/platform/platform-resources/src/idea/Keymap_Eclipse.xml index 7198e1f92409..6f749a03b42b 100644 --- a/platform/platform-resources/src/idea/Keymap_Eclipse.xml +++ b/platform/platform-resources/src/idea/Keymap_Eclipse.xml @@ -59,7 +59,7 @@
- + diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index 55c40538ce57..d571195faca2 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -57,6 +57,7 @@ + From 7a184ad9060b85adbb2adfba26c29c70ac183ecb Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Tue, 9 Nov 2010 13:49:59 +0300 Subject: [PATCH 039/257] IDEA-60781 After formatting cursor jumps from indented position to beginning of the line. Caret offset is normalized during calculations now --- .../psi/impl/source/codeStyle/CodeStyleManagerImpl.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java index e3db5036e4cb..90c00162f75e 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java @@ -156,10 +156,11 @@ public class CodeStyleManagerImpl extends CodeStyleManager { // So, we check if it should be preserved and restore it after formatting if necessary boolean fixCaretPosition = false; if (editor != null) { - int caretOffset = editor.getCaretModel().getOffset(); Document document = editor.getDocument(); + int caretOffset = editor.getCaretModel().getOffset(); + caretOffset = Math.max(Math.min(caretOffset, document.getTextLength() - 1), 0); CharSequence text = document.getCharsSequence(); - int caretLine = document.getLineNumber(Math.max(Math.min(caretOffset, document.getTextLength() - 1), 0)); + int caretLine = document.getLineNumber(caretOffset); int lineStartOffset = document.getLineStartOffset(caretLine); fixCaretPosition = true; for (int i = caretOffset; i>= lineStartOffset; i--) { From 114e586d32d5c3e938029b1c4cdcaf471dafcfb4 Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Tue, 9 Nov 2010 13:54:01 +0300 Subject: [PATCH 040/257] check if ddms service corrupted before debug and offer to restart --- .../android/run/AndroidDebugRunner.java | 20 --------- .../run/AndroidRunConfigurationBase.java | 42 +++++++++++++++++-- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/plugins/android/src/org/jetbrains/android/run/AndroidDebugRunner.java b/plugins/android/src/org/jetbrains/android/run/AndroidDebugRunner.java index 6dc30cfbeb0e..6d21ae5749be 100644 --- a/plugins/android/src/org/jetbrains/android/run/AndroidDebugRunner.java +++ b/plugins/android/src/org/jetbrains/android/run/AndroidDebugRunner.java @@ -35,10 +35,8 @@ import com.intellij.execution.ui.RunContentManager; import com.intellij.execution.ui.layout.LayoutViewOptions; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Key; import com.intellij.psi.PsiClass; -import org.jetbrains.android.actions.AndroidEnableDdmsAction; import org.jetbrains.android.dom.manifest.Instrumentation; import org.jetbrains.android.dom.manifest.Manifest; import org.jetbrains.android.logcat.AndroidLogcatUtil; @@ -83,24 +81,6 @@ public class AndroidDebugRunner extends DefaultProgramRunner { } } - @Override - public void execute(@NotNull Executor executor, - @NotNull ExecutionEnvironment env, - @Nullable Callback callback) throws ExecutionException { - if (!AndroidEnableDdmsAction.isDdmsEnabled()) { - Project project = env.getProject(); - int result = Messages.showYesNoDialog(project, AndroidBundle.message("android.ddms.disabled.error"), - AndroidBundle.message("android.ddms.disabled.dialog.title"), - Messages.getQuestionIcon()); - if (result != 0) { - return; - } - AndroidEnableDdmsAction.setDdmsEnabled(project, true); - } - - super.execute(executor, env, callback); - } - @Override protected RunContentDescriptor doExecute(final Project project, final Executor executor, diff --git a/plugins/android/src/org/jetbrains/android/run/AndroidRunConfigurationBase.java b/plugins/android/src/org/jetbrains/android/run/AndroidRunConfigurationBase.java index 8a75ae586f56..ea8e4d7420ed 100644 --- a/plugins/android/src/org/jetbrains/android/run/AndroidRunConfigurationBase.java +++ b/plugins/android/src/org/jetbrains/android/run/AndroidRunConfigurationBase.java @@ -16,14 +16,14 @@ package org.jetbrains.android.run; -import com.android.ddmlib.IDevice; -import com.android.ddmlib.Log; +import com.android.ddmlib.*; import com.android.sdklib.internal.avd.AvdManager; import com.intellij.CommonBundle; import com.intellij.diagnostic.logging.LogConsole; import com.intellij.execution.ExecutionException; import com.intellij.execution.Executor; import com.intellij.execution.configurations.*; +import com.intellij.execution.executors.DefaultDebugExecutor; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.ui.ConsoleView; import com.intellij.ide.util.PropertiesComponent; @@ -45,6 +45,7 @@ import com.intellij.util.PsiNavigateUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.xml.GenericAttributeValue; import org.jdom.Element; +import org.jetbrains.android.actions.AndroidEnableDdmsAction; import org.jetbrains.android.dom.manifest.Manifest; import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.android.facet.AndroidFacetConfiguration; @@ -171,9 +172,29 @@ public abstract class AndroidRunConfigurationBase extends ModuleBasedConfigurati if (facet == null) { throw new ExecutionException(AndroidBundle.message("no.facet.error", module.getName())); } + + Project project = env.getProject(); + + if (DefaultDebugExecutor.EXECUTOR_ID.equals(executor.getId())) { + boolean ddmsEnabled = AndroidEnableDdmsAction.isDdmsEnabled(); + if (ddmsEnabled && isDdmsCorrupted(facet)) { + ddmsEnabled = false; + AndroidEnableDdmsAction.setDdmsEnabled(project, false); + } + + if (!ddmsEnabled) { + int result = Messages.showYesNoDialog(project, AndroidBundle.message("android.ddms.disabled.error"), + AndroidBundle.message("android.ddms.disabled.dialog.title"), + Messages.getQuestionIcon()); + if (result != 0) { + return null; + } + AndroidEnableDdmsAction.setDdmsEnabled(project, true); + } + } + AndroidFacetConfiguration configuration = facet.getConfiguration(); AndroidPlatform platform = configuration.getAndroidPlatform(); - Project project = module.getProject(); if (platform == null) { Messages.showErrorDialog(project, AndroidBundle.message("specify.platform.error"), CommonBundle.getErrorTitle()); ModulesConfigurator.showFacetSettingsDialog(facet, null); @@ -208,6 +229,21 @@ public abstract class AndroidRunConfigurationBase extends ModuleBasedConfigurati return null; } + private static boolean isDdmsCorrupted(@NotNull AndroidFacet facet) { + AndroidDebugBridge bridge = facet.getDebugBridge(); + if (bridge != null) { + IDevice[] devices = bridge.getDevices(); + if (devices.length > 0) { + Client[] clients = devices[0].getClients(); + if (clients.length > 0) { + ClientData clientData = clients[0].getClientData(); + return clientData == null || clientData.getVmIdentifier() == null; + } + } + } + return false; + } + @Nullable private static String getPackageName(AndroidFacet facet) { Manifest manifest = facet.getManifest(); From d1164f1c361c729c231d9db2a9e82ea9d1f0d0cb Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 9 Nov 2010 14:10:04 +0300 Subject: [PATCH 041/257] allow specifying custom name for "jump to source" action (IDEA-59460) --- .../impl/nodes/NamedLibraryElementNode.java | 8 ++++++- .../com/intellij/pom/NavigatableWithText.java | 23 +++++++++++++++++++ .../actions/BaseNavigateToSourceAction.java | 18 +++++++++++---- 3 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 platform/platform-api/src/com/intellij/pom/NavigatableWithText.java diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/NamedLibraryElementNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/NamedLibraryElementNode.java index 0ab7de8454bd..0014de0dd56c 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/NamedLibraryElementNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/NamedLibraryElementNode.java @@ -33,6 +33,7 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.NavigatableWithText; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -40,7 +41,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -public class NamedLibraryElementNode extends ProjectViewNode{ +public class NamedLibraryElementNode extends ProjectViewNode implements NavigatableWithText { private static final Icon GENERIC_JDK_ICON = IconLoader.getIcon("/general/jdk.png"); private static final Icon LIB_ICON_OPEN = IconLoader.getIcon("/nodes/ppLibOpen.png"); private static final Icon LIB_ICON_CLOSED = IconLoader.getIcon("/nodes/ppLibClosed.png"); @@ -123,4 +124,9 @@ public class NamedLibraryElementNode extends ProjectViewNode Date: Tue, 9 Nov 2010 14:16:56 +0300 Subject: [PATCH 042/257] Fix: IDEA-60858 (Grails: Support of 'g:fieldValue' tag) --- .../CompleteReferenceExpression.java | 2 +- .../lang/psi/util/GroovyPropertyUtils.java | 31 +++++++++++++++++-- .../GroovyStringLiteralManipulator.java | 11 ++++++- .../rename/RenameGroovyPropertyProcessor.java | 7 ++--- 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java index 06e63a6e9a04..76a72c5f40e5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java @@ -290,7 +290,7 @@ public class CompleteReferenceExpression { return result.toArray(new LookupElement[result.size()]); } - private static LookupElementBuilder createPropertyLookupElement(String propName, PsiType propType, PsiSubstitutor substitutor) { + public static LookupElementBuilder createPropertyLookupElement(String propName, PsiType propType, PsiSubstitutor substitutor) { if (!PsiUtil.isValidReferenceName(propName)) { propName = "'" + propName + "'"; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyPropertyUtils.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyPropertyUtils.java index 9d9a89f8cb8f..01d35abf7cae 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyPropertyUtils.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyPropertyUtils.java @@ -28,6 +28,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod; import java.beans.Introspector; +import java.util.ArrayList; +import java.util.List; /** * @author ilyas @@ -82,8 +84,33 @@ public class GroovyPropertyUtils { return null; } + public static List getAllPropertyGetters(@NotNull PsiClass aClass, @Nullable Boolean isStatic, boolean checkSuperClasses) { + PsiMethod[] methods; + if (checkSuperClasses) { + methods = aClass.getAllMethods(); + } + else { + methods = aClass.getMethods(); + } + + List res = new ArrayList(methods.length); + + for (PsiMethod method : methods) { + if (isStatic != null && method.hasModifierProperty(PsiModifier.STATIC) != isStatic) continue; + + if (isSimplePropertyGetter(method)) { + res.add(method); + } + } + + return res; + } + @Nullable - public static PsiMethod findPropertyGetter(PsiClass aClass, String propertyName, boolean isStatic, boolean checkSuperClasses) { + public static PsiMethod findPropertyGetter(@Nullable PsiClass aClass, + String propertyName, + @Nullable Boolean isStatic, + boolean checkSuperClasses) { if (aClass == null) return null; PsiMethod[] methods; if (checkSuperClasses) { @@ -94,7 +121,7 @@ public class GroovyPropertyUtils { } for (PsiMethod method : methods) { - if (method.hasModifierProperty(PsiModifier.STATIC) != isStatic) continue; + if (isStatic != null && method.hasModifierProperty(PsiModifier.STATIC) != isStatic) continue; if (isSimplePropertyGetter(method)) { if (propertyName.equals(getPropertyNameByGetter(method))) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/GroovyStringLiteralManipulator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/GroovyStringLiteralManipulator.java index 1055695db990..1f05cf5c2096 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/GroovyStringLiteralManipulator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/GroovyStringLiteralManipulator.java @@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.lang.resolve; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.AbstractElementManipulator; +import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; @@ -30,7 +31,15 @@ public class GroovyStringLiteralManipulator extends AbstractElementManipulator Date: Tue, 9 Nov 2010 14:28:47 +0300 Subject: [PATCH 043/257] already disposed --- .../xdebugger/impl/ui/ExecutionPointHighlighter.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/ExecutionPointHighlighter.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/ExecutionPointHighlighter.java index 8c8c89af01ad..96d94493bda5 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/ExecutionPointHighlighter.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/ExecutionPointHighlighter.java @@ -16,20 +16,20 @@ package com.intellij.xdebugger.impl.ui; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.OpenFileDescriptor; -import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.ui.DebuggerColors; -import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author nik @@ -49,7 +49,9 @@ public class ExecutionPointHighlighter { public void show(final @NotNull XSourcePosition position, final boolean useSelection) { DebuggerUIUtil.invokeOnEventDispatch(new Runnable() { public void run() { - doShow(position, useSelection); + if (!myProject.isDisposed()) { + doShow(position, useSelection); + } } }); } From 63cabf0290e8d89dd4be0955b868d835be25dfd1 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Tue, 9 Nov 2010 15:02:04 +0300 Subject: [PATCH 044/257] Correct creation of ID objects --- .../android/src/org/jetbrains/android/AndroidIdIndex.java | 5 ++--- .../android/resourceManagers/LocalResourceManager.java | 4 ++-- .../src/org/jetbrains/android/util/AndroidResourceUtil.java | 2 +- .../html/impl/Html5CustomAttributeDescriptorsProvider.java | 2 +- .../com/intellij/html/index/Html5CustomAttributesIndex.java | 5 ++--- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/plugins/android/src/org/jetbrains/android/AndroidIdIndex.java b/plugins/android/src/org/jetbrains/android/AndroidIdIndex.java index 29a02b43699f..18654c52154e 100644 --- a/plugins/android/src/org/jetbrains/android/AndroidIdIndex.java +++ b/plugins/android/src/org/jetbrains/android/AndroidIdIndex.java @@ -41,8 +41,7 @@ import java.util.Map; public class AndroidIdIndex extends ScalarIndexExtension { public static final String[] RES_TYPES_CONTAINING_ID_DECLARATIONS = {SdkConstants.FD_LAYOUT, SdkConstants.FD_MENU}; - public static final ID ID = new ID("android.id.index") { - }; + public static final ID INDEX_ID = ID.create("android.id.index"); public static final String MARKER = "$"; @@ -96,7 +95,7 @@ public class AndroidIdIndex extends ScalarIndexExtension { @Override public ID getName() { - return ID; + return INDEX_ID; } @Override diff --git a/plugins/android/src/org/jetbrains/android/resourceManagers/LocalResourceManager.java b/plugins/android/src/org/jetbrains/android/resourceManagers/LocalResourceManager.java index 2b5469e204b2..7123802eff66 100644 --- a/plugins/android/src/org/jetbrains/android/resourceManagers/LocalResourceManager.java +++ b/plugins/android/src/org/jetbrains/android/resourceManagers/LocalResourceManager.java @@ -150,9 +150,9 @@ public class LocalResourceManager extends ResourceManager { List result = new ArrayList(); Project project = myModule.getProject(); GlobalSearchScope scope = GlobalSearchScope.projectScope(myModule.getProject()); - for (String key : FileBasedIndex.getInstance().getAllKeys(AndroidIdIndex.ID, project)) { + for (String key : FileBasedIndex.getInstance().getAllKeys(AndroidIdIndex.INDEX_ID, project)) { if (!AndroidIdIndex.MARKER.equals(key)) { - if (FileBasedIndex.getInstance().getValues(AndroidIdIndex.ID, key, scope).size() > 0) { + if (FileBasedIndex.getInstance().getValues(AndroidIdIndex.INDEX_ID, key, scope).size() > 0) { result.add(key); } } diff --git a/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java b/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java index a3c6a8ccda47..8f9361242ebb 100644 --- a/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java +++ b/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java @@ -356,7 +356,7 @@ public class AndroidResourceUtil { public static void collectIdDeclarations(@NotNull final String id, Module module, final List targets) { Collection files = - FileBasedIndex.getInstance().getContainingFiles(AndroidIdIndex.ID, id, GlobalSearchScope.projectScope(module.getProject())); + FileBasedIndex.getInstance().getContainingFiles(AndroidIdIndex.INDEX_ID, id, GlobalSearchScope.projectScope(module.getProject())); PsiManager psiManager = PsiManager.getInstance(module.getProject()); for (VirtualFile file : files) { PsiFile psiFile = psiManager.findFile(file); diff --git a/xml/impl/src/com/intellij/html/impl/Html5CustomAttributeDescriptorsProvider.java b/xml/impl/src/com/intellij/html/impl/Html5CustomAttributeDescriptorsProvider.java index 59e0f2fcbf0c..a75e395fdec2 100644 --- a/xml/impl/src/com/intellij/html/impl/Html5CustomAttributeDescriptorsProvider.java +++ b/xml/impl/src/com/intellij/html/impl/Html5CustomAttributeDescriptorsProvider.java @@ -42,7 +42,7 @@ public class Html5CustomAttributeDescriptorsProvider implements XmlAttributeDesc currentAttrs.add(attribute.getName()); } final List result = new ArrayList(); - FileBasedIndex.getInstance().processAllKeys(Html5CustomAttributesIndex.ID, new Processor() { + FileBasedIndex.getInstance().processAllKeys(Html5CustomAttributesIndex.INDEX_ID, new Processor() { @Override public boolean process(String s) { boolean add = true; diff --git a/xml/impl/src/com/intellij/html/index/Html5CustomAttributesIndex.java b/xml/impl/src/com/intellij/html/index/Html5CustomAttributesIndex.java index d05c157d9857..47478b9de007 100644 --- a/xml/impl/src/com/intellij/html/index/Html5CustomAttributesIndex.java +++ b/xml/impl/src/com/intellij/html/index/Html5CustomAttributesIndex.java @@ -42,8 +42,7 @@ import java.util.Map; * @author Eugene.Kudelevsky */ public class Html5CustomAttributesIndex extends ScalarIndexExtension { - public static final ID ID = new ID("html5.custom.attributes.index") { - }; + public static final ID INDEX_ID = ID.create("html5.custom.attributes.index"); private final DataIndexer myIndexer = new DataIndexer() { @NotNull @@ -84,7 +83,7 @@ public class Html5CustomAttributesIndex extends ScalarIndexExtension { @Override public ID getName() { - return ID; + return INDEX_ID; } @Override From ee00dab1bdf02a3cedfdd0d350bf78f19884913a Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Tue, 9 Nov 2010 15:08:59 +0300 Subject: [PATCH 045/257] remove unnecesary conversion to long --- platform/lang-api/src/com/intellij/util/indexing/ID.java | 2 +- .../lang-impl/src/com/intellij/util/indexing/IndexingStamp.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/lang-api/src/com/intellij/util/indexing/ID.java b/platform/lang-api/src/com/intellij/util/indexing/ID.java index 62e1b05ceeb0..e400793c745c 100644 --- a/platform/lang-api/src/com/intellij/util/indexing/ID.java +++ b/platform/lang-api/src/com/intellij/util/indexing/ID.java @@ -130,7 +130,7 @@ public class ID { return myName; } - public long getUniqueId() { + public int getUniqueId() { return myUniqueId; } diff --git a/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java b/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java index d8dbdf340c5d..dfbfa3bf082c 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java @@ -76,7 +76,7 @@ public class IndexingStamp { myIndexStamps.forEachEntry(new TObjectLongProcedure>() { public boolean execute(final ID id, final long timestamp) { try { - DataInputOutputUtil.writeINT(stream, (int)id.getUniqueId()); + DataInputOutputUtil.writeINT(stream, id.getUniqueId()); DataInputOutputUtil.writeTIME(stream, timestamp); count[0]++; return true; From 7a798bb1f950bc5dd6d47bd56c53d7d85bf07a44 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Tue, 9 Nov 2010 15:14:46 +0300 Subject: [PATCH 046/257] correct initialization sequence --- .../src/com/intellij/ide/commander/ProjectListBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/ide/commander/ProjectListBuilder.java b/platform/lang-impl/src/com/intellij/ide/commander/ProjectListBuilder.java index 26c5d9b1d548..bd7c9682fd48 100644 --- a/platform/lang-impl/src/com/intellij/ide/commander/ProjectListBuilder.java +++ b/platform/lang-impl/src/com/intellij/ide/commander/ProjectListBuilder.java @@ -51,6 +51,7 @@ public class ProjectListBuilder extends AbstractListBuilder { super(project, panel.getList(), panel.getModel(), treeStructure, comparator, showRoot); myList.setCellRenderer(new ColoredCommanderRenderer(panel)); + myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, myProject); myPsiTreeChangeListener = new MyPsiTreeChangeListener(); PsiManager.getInstance(myProject).addPsiTreeChangeListener(myPsiTreeChangeListener); @@ -59,7 +60,6 @@ public class ProjectListBuilder extends AbstractListBuilder { myCopyPasteListener = new MyCopyPasteListener(); CopyPasteManager.getInstance().addContentChangedListener(myCopyPasteListener); buildRoot(); - myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, myProject); } protected void updateParentTitle() { From a2dc19b22d4a92777fd35af866bb9698a07c7428 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Tue, 9 Nov 2010 15:17:17 +0300 Subject: [PATCH 047/257] do not treat IOException as an error --- .../src/com/intellij/execution/process/OSProcessHandler.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/platform-api/src/com/intellij/execution/process/OSProcessHandler.java b/platform/platform-api/src/com/intellij/execution/process/OSProcessHandler.java index 31e2b6dd54ac..e6bf49e10b4b 100644 --- a/platform/platform-api/src/com/intellij/execution/process/OSProcessHandler.java +++ b/platform/platform-api/src/com/intellij/execution/process/OSProcessHandler.java @@ -246,6 +246,9 @@ public class OSProcessHandler extends ProcessHandler { } catch (InterruptedException ignore) { } + catch (IOException e) { + LOG.info(e); + } catch (Exception e) { LOG.error(e); } From 30acdd8039a7c7c8fbd621d0f8d723d79eac8105 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Tue, 9 Nov 2010 15:29:28 +0300 Subject: [PATCH 048/257] fix NPE --- .../src/com/intellij/psi/stubs/SerializationManagerImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/lang-api/src/com/intellij/psi/stubs/SerializationManagerImpl.java b/platform/lang-api/src/com/intellij/psi/stubs/SerializationManagerImpl.java index 930d9e7af5da..e90ab4138623 100644 --- a/platform/lang-api/src/com/intellij/psi/stubs/SerializationManagerImpl.java +++ b/platform/lang-api/src/com/intellij/psi/stubs/SerializationManagerImpl.java @@ -121,6 +121,9 @@ public class SerializationManagerImpl extends SerializationManager implements Ap } private int persistentId(@NotNull final StubSerializer serializer) throws IOException { + if (myNameStorage == null) { + throw new IOException("SerializationManager's name storage failed to initialize"); + } return myNameStorage.enumerate(serializer.getExternalId()); } From ac55d814bb9a022830124b344441d0a209fa7f25 Mon Sep 17 00:00:00 2001 From: "Rustam.Vishnyakov" Date: Tue, 9 Nov 2010 14:36:20 +0300 Subject: [PATCH 049/257] JavaScript library scope filter --- .../LangScriptingContextConfigurable.java | 3 +- .../ScriptingLibraryMappings.java | 40 +++++++++++++++++++ .../ui/ScriptingContextsConfigurable.java | 2 +- .../scripting/ScriptingLibraryTable.java | 8 ++++ 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/LangScriptingContextConfigurable.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/LangScriptingContextConfigurable.java index cec9a3a05c46..84b243c7e81e 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/LangScriptingContextConfigurable.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/LangScriptingContextConfigurable.java @@ -87,7 +87,6 @@ public abstract class LangScriptingContextConfigurable implements Configurable, @Override public Configurable[] getConfigurables() { - //return new Configurable[] {myContextsConfigurable}; - return new Configurable[] {}; + return new Configurable[] {myContextsConfigurable}; } } diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java index 75b1931d158f..777172e6141d 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryMappings.java @@ -157,6 +157,46 @@ public class ScriptingLibraryMappings extends LanguagePerFileMappings Date: Tue, 9 Nov 2010 15:33:49 +0300 Subject: [PATCH 050/257] JavaScript library scope filter --- .../ide/scriptingContext/ui/ScriptingContextsConfigurable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/ScriptingContextsConfigurable.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/ScriptingContextsConfigurable.java index 72044f9ee52c..aab4ef3bd341 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/ScriptingContextsConfigurable.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/ScriptingContextsConfigurable.java @@ -44,7 +44,7 @@ public class ScriptingContextsConfigurable extends LanguagePerFileConfigurable Date: Tue, 9 Nov 2010 15:52:12 +0300 Subject: [PATCH 051/257] IDEA-60380 save selected rows when enter pressed --- .../src/org/jetbrains/android/run/DeviceChooser.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/plugins/android/src/org/jetbrains/android/run/DeviceChooser.java b/plugins/android/src/org/jetbrains/android/run/DeviceChooser.java index 9f3abbfd0130..aefa8dac3de7 100644 --- a/plugins/android/src/org/jetbrains/android/run/DeviceChooser.java +++ b/plugins/android/src/org/jetbrains/android/run/DeviceChooser.java @@ -61,6 +61,8 @@ public class DeviceChooser extends DialogWrapper implements AndroidDebugBridge.I private JTable myDeviceTable; private static final String[] COLUMN_TITLES = new String[]{"Serial Number", "AVD name", "State", "Compatible"}; + private int[] mySelectedRows; + public DeviceChooser(@NotNull AndroidFacet facet, boolean multipleSelection, @Nullable String[] selectedSerials) { super(facet.getModule().getProject(), true); setTitle(AndroidBundle.message("choose.device.dialog.title")); @@ -191,13 +193,19 @@ public class DeviceChooser extends DialogWrapper implements AndroidDebugBridge.I } } + @Override + protected void doOKAction() { + mySelectedRows = myDeviceTable.getSelectedRows(); + super.doOKAction(); + } + protected JComponent createCenterPanel() { return myPanel; } @NotNull public IDevice[] getSelectedDevices() { - int[] rows = myDeviceTable.getSelectedRows(); + int[] rows = mySelectedRows != null ? mySelectedRows : myDeviceTable.getSelectedRows(); List result = new ArrayList(); for (int row : rows) { if (row >= 0) { From 7a7aa3e75a685fd5b76ebd4997b9a28dfcdecd94 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Tue, 9 Nov 2010 15:52:53 +0300 Subject: [PATCH 052/257] IDEA-35453 Resource bundle editor: Assertion failed on grouping keys by delimiter, which is the first char in key Precondition is corrected in order to consider situation when bundle key starts with the target separator --- .../PropertiesGroupingStructureViewComponent.java | 7 +------ .../structureView/GroupByWordPrefixes.java | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/PropertiesGroupingStructureViewComponent.java b/plugins/properties/src/com/intellij/lang/properties/editor/PropertiesGroupingStructureViewComponent.java index 2eda40b1eea5..17fbf37814de 100644 --- a/plugins/properties/src/com/intellij/lang/properties/editor/PropertiesGroupingStructureViewComponent.java +++ b/plugins/properties/src/com/intellij/lang/properties/editor/PropertiesGroupingStructureViewComponent.java @@ -23,7 +23,6 @@ import com.intellij.openapi.actionSystem.ex.ComboBoxAction; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; -import com.intellij.ui.GuiUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NonNls; @@ -67,14 +66,9 @@ public class PropertiesGroupingStructureViewComponent extends StructureViewCompo public final void update(AnActionEvent e) { Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); if (project == null) return; - boolean isGroupActive = isActionActive(GroupByWordPrefixes.ID); String separator = getCurrentSeparator(); Presentation presentation = e.getPresentation(); presentation.setText(separator); - presentation.setEnabled(isGroupActive); - if (myPanel != null) { - GuiUtils.enableChildren(myPanel, isGroupActive); - } } private String getCurrentSeparator() { @@ -136,6 +130,7 @@ public class PropertiesGroupingStructureViewComponent extends StructureViewCompo } ((PropertiesGroupingStructureViewModel)getTreeModel()).setSeparator(separator); + setActionActive(GroupByWordPrefixes.ID, true); rebuild(); } } diff --git a/plugins/properties/src/com/intellij/lang/properties/structureView/GroupByWordPrefixes.java b/plugins/properties/src/com/intellij/lang/properties/structureView/GroupByWordPrefixes.java index c04e92a7ab65..2c5f5f987279 100644 --- a/plugins/properties/src/com/intellij/lang/properties/structureView/GroupByWordPrefixes.java +++ b/plugins/properties/src/com/intellij/lang/properties/structureView/GroupByWordPrefixes.java @@ -32,7 +32,7 @@ import java.util.*; /** * @author cdr */ -public class GroupByWordPrefixes implements Grouper { +public class GroupByWordPrefixes implements Grouper, Sorter { private static final Logger LOG = Logger.getInstance("#com.intellij.lang.properties.structureView.GroupByWordPrefixes"); @NonNls public static final String ID = "GROUP_BY_PREFIXES"; private String mySeparator; @@ -73,7 +73,7 @@ public class GroupByWordPrefixes implements Grouper { text = ((ResourceBundlePropertyStructureViewElement)element).getValue(); } if (text == null) continue; - LOG.assertTrue(text.startsWith(parentPrefix)); + LOG.assertTrue(text.startsWith(parentPrefix) || text.startsWith(mySeparator)); List words = StringUtil.split(text, mySeparator); keys.add(new Key(words, element)); } @@ -158,6 +158,16 @@ public class GroupByWordPrefixes implements Grouper { return ID; } + @Override + public Comparator getComparator() { + return Sorter.ALPHA_SORTER.getComparator(); + } + + @Override + public boolean isVisible() { + return true; + } + private static class Key { final List words; final TreeElement node; From 3a0332486c54ca6077237241b61767e686e729be Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Tue, 9 Nov 2010 16:38:20 +0300 Subject: [PATCH 053/257] IDEA-53703 warn when attempting to debug on device if android:debuggable="true" is not present --- .../messages/AndroidBundle.properties | 3 +- .../run/AndroidRunConfigurationBase.java | 103 +++++++++++++----- .../jetbrains/android/run/DeviceChooser.java | 2 +- 3 files changed, 81 insertions(+), 27 deletions(-) diff --git a/plugins/android/resources/messages/AndroidBundle.properties b/plugins/android/resources/messages/AndroidBundle.properties index ae2649fba0dc..6e7666944d41 100644 --- a/plugins/android/resources/messages/AndroidBundle.properties +++ b/plugins/android/resources/messages/AndroidBundle.properties @@ -212,4 +212,5 @@ android.run.configuration.general.tab.title=General android.run.configuration.emulator.tab.title=Emulator android.run.configuration.logcat.tab.title=Logcat android.facet.settings.apk.path.label=APK path: -android.run.confguration.deploy.and.install.check.box=Deplo&y application \ No newline at end of file +android.run.confguration.deploy.and.install.check.box=Deplo&y application +android.manifest.debuggable.attribute.not.true.warning=The manifest 'debuggable' attribute isn't set to 'true'.\nYou have to set it to true in order to debug on a device.\nWould you like to do it? \ No newline at end of file diff --git a/plugins/android/src/org/jetbrains/android/run/AndroidRunConfigurationBase.java b/plugins/android/src/org/jetbrains/android/run/AndroidRunConfigurationBase.java index ea8e4d7420ed..86c60e02ed90 100644 --- a/plugins/android/src/org/jetbrains/android/run/AndroidRunConfigurationBase.java +++ b/plugins/android/src/org/jetbrains/android/run/AndroidRunConfigurationBase.java @@ -27,6 +27,7 @@ import com.intellij.execution.executors.DefaultDebugExecutor; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.ui.ConsoleView; import com.intellij.ide.util.PropertiesComponent; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; @@ -44,8 +45,10 @@ import com.intellij.util.ArrayUtil; import com.intellij.util.PsiNavigateUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.xml.GenericAttributeValue; +import com.intellij.util.xml.converters.values.BooleanValueConverter; import org.jdom.Element; import org.jetbrains.android.actions.AndroidEnableDdmsAction; +import org.jetbrains.android.dom.manifest.Application; import org.jetbrains.android.dom.manifest.Manifest; import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.android.facet.AndroidFacetConfiguration; @@ -163,6 +166,15 @@ public abstract class AndroidRunConfigurationBase extends ModuleBasedConfigurati return true; } + private static boolean containsRealDevice(@NotNull IDevice[] devices) { + for (IDevice device : devices) { + if (!device.isEmulator()) { + return true; + } + } + return false; + } + public RunProfileState getState(@NotNull final Executor executor, @NotNull ExecutionEnvironment env) throws ExecutionException { final Module module = getConfigurationModule().getModule(); if (module == null) { @@ -175,21 +187,13 @@ public abstract class AndroidRunConfigurationBase extends ModuleBasedConfigurati Project project = env.getProject(); - if (DefaultDebugExecutor.EXECUTOR_ID.equals(executor.getId())) { - boolean ddmsEnabled = AndroidEnableDdmsAction.isDdmsEnabled(); - if (ddmsEnabled && isDdmsCorrupted(facet)) { - ddmsEnabled = false; - AndroidEnableDdmsAction.setDdmsEnabled(project, false); + boolean debug = DefaultDebugExecutor.EXECUTOR_ID.equals(executor.getId()); + if (debug) { + if (!activateDdmsIfNeccessary(facet)) { + return null; } - - if (!ddmsEnabled) { - int result = Messages.showYesNoDialog(project, AndroidBundle.message("android.ddms.disabled.error"), - AndroidBundle.message("android.ddms.disabled.dialog.title"), - Messages.getQuestionIcon()); - if (result != 0) { - return null; - } - AndroidEnableDdmsAction.setDdmsEnabled(project, true); + if (!CHOOSE_DEVICE_MANUALLY) { + checkDebuggableOption(facet); } } @@ -210,7 +214,17 @@ public abstract class AndroidRunConfigurationBase extends ModuleBasedConfigurati if (platform.getSdk().getDebugBridge(project) == null) return null; String[] deviceSerialNumbers = ArrayUtil.EMPTY_STRING_ARRAY; if (CHOOSE_DEVICE_MANUALLY) { - deviceSerialNumbers = chooseDevicesManually(facet); + IDevice[] devices = chooseDevicesManually(facet); + if (devices.length > 0) { + if (debug && containsRealDevice(devices)) { + checkDebuggableOption(facet); + } + deviceSerialNumbers = new String[devices.length]; + for (int i = 0; i < devices.length; i++) { + deviceSerialNumbers[i] = devices[i].getSerialNumber(); + PropertiesComponent.getInstance(getProject()).setValue(ANDROID_TARGET_DEVICES_PROPERTY, toString(deviceSerialNumbers)); + } + } if (deviceSerialNumbers.length == 0) return null; } AndroidApplicationLauncher applicationLauncher = getApplicationLauncher(facet); @@ -229,6 +243,51 @@ public abstract class AndroidRunConfigurationBase extends ModuleBasedConfigurati return null; } + private static void checkDebuggableOption(@NotNull AndroidFacet facet) { + Manifest manifest = facet.getManifest(); + // validated in checkConfiguration() + assert manifest != null; + final Application application = manifest.getApplication(); + if (application != null) { + String debuggable = application.getDebuggable().getValue(); + BooleanValueConverter booleanValueConverter = BooleanValueConverter.getInstance(true); + if (debuggable == null || !booleanValueConverter.isTrue(debuggable)) { + Project project = facet.getModule().getProject(); + int result = Messages.showYesNoDialog(project, AndroidBundle.message("android.manifest.debuggable.attribute.not.true.warning"), + CommonBundle.getWarningTitle(), + Messages.getWarningIcon()); + if (result == 0) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + application.getDebuggable().setValue("true"); + } + }); + } + } + } + } + + private static boolean activateDdmsIfNeccessary(@NotNull AndroidFacet facet) { + Project project = facet.getModule().getProject(); + boolean ddmsEnabled = AndroidEnableDdmsAction.isDdmsEnabled(); + if (ddmsEnabled && isDdmsCorrupted(facet)) { + ddmsEnabled = false; + AndroidEnableDdmsAction.setDdmsEnabled(project, false); + } + + if (!ddmsEnabled) { + int result = Messages.showYesNoDialog(project, AndroidBundle.message("android.ddms.disabled.error"), + AndroidBundle.message("android.ddms.disabled.dialog.title"), + Messages.getQuestionIcon()); + if (result != 0) { + return false; + } + AndroidEnableDdmsAction.setDdmsEnabled(project, true); + } + return true; + } + private static boolean isDdmsCorrupted(@NotNull AndroidFacet facet) { AndroidDebugBridge bridge = facet.getDebugBridge(); if (bridge != null) { @@ -308,22 +367,16 @@ public abstract class AndroidRunConfigurationBase extends ModuleBasedConfigurati } @NotNull - private String[] chooseDevicesManually(@NotNull AndroidFacet facet) { - PropertiesComponent propertiesComponent = PropertiesComponent.getInstance(getProject()); - String value = propertiesComponent.getValue(ANDROID_TARGET_DEVICES_PROPERTY); + private IDevice[] chooseDevicesManually(@NotNull AndroidFacet facet) { + String value = PropertiesComponent.getInstance(getProject()).getValue(ANDROID_TARGET_DEVICES_PROPERTY); String[] selectedSerials = value != null ? fromString(value) : null; DeviceChooser chooser = new DeviceChooser(facet, supportMultipleDevices(), selectedSerials); chooser.show(); IDevice[] devices = chooser.getSelectedDevices(); if (chooser.getExitCode() != DeviceChooser.OK_EXIT_CODE || devices.length == 0) { - return ArrayUtil.EMPTY_STRING_ARRAY; + return DeviceChooser.EMPTY_DEVICE_ARRAY; } - String[] serials = new String[devices.length]; - for (int i = 0; i < devices.length; i++) { - serials[i] = devices[i].getSerialNumber(); - } - propertiesComponent.setValue(ANDROID_TARGET_DEVICES_PROPERTY, toString(serials)); - return serials; + return devices; } @Override diff --git a/plugins/android/src/org/jetbrains/android/run/DeviceChooser.java b/plugins/android/src/org/jetbrains/android/run/DeviceChooser.java index aefa8dac3de7..7dbc0fb1ca5d 100644 --- a/plugins/android/src/org/jetbrains/android/run/DeviceChooser.java +++ b/plugins/android/src/org/jetbrains/android/run/DeviceChooser.java @@ -53,7 +53,7 @@ import static com.intellij.openapi.util.text.StringUtil.capitalize; * To change this template use File | Settings | File Templates. */ public class DeviceChooser extends DialogWrapper implements AndroidDebugBridge.IDeviceChangeListener { - private static final IDevice[] EMPTY_DEVICE_ARRAY = new IDevice[0]; + public static final IDevice[] EMPTY_DEVICE_ARRAY = new IDevice[0]; private final AndroidFacet myFacet; @Nullable From 66bd5cc5a70a31d78920579a0828cf4c9106a666 Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 9 Nov 2010 13:37:53 +0300 Subject: [PATCH 054/257] fixed icons for multi-line error nodes --- .../xdebugger/impl/ui/tree/nodes/MessageTreeNode.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/MessageTreeNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/MessageTreeNode.java index ec47fecf023d..b3e92d09bf83 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/MessageTreeNode.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/MessageTreeNode.java @@ -35,7 +35,6 @@ import java.util.List; * @author nik */ public class MessageTreeNode extends XDebuggerTreeNode { - private static final EmptyIcon EMPTY_ICON = new EmptyIcon(XDebuggerUIConstants.ERROR_MESSAGE_ICON); private boolean myEllipsis; private XDebuggerTreeNodeHyperlink myLink; @@ -106,8 +105,8 @@ public class MessageTreeNode extends XDebuggerTreeNode { List messages = new ArrayList(1); final List lines = StringUtil.split(errorMessage, "\n"); for (int i = 0; i < lines.size(); i++) { - final Icon icon = i == 0 ? XDebuggerUIConstants.ERROR_MESSAGE_ICON : EMPTY_ICON; - messages.add(new MessageTreeNode(tree, parent, lines.get(i), XDebuggerUIConstants.ERROR_MESSAGE_ATTRIBUTES, icon, i == 0 ? link : null)); + messages.add(new MessageTreeNode(tree, parent, lines.get(i), XDebuggerUIConstants.ERROR_MESSAGE_ATTRIBUTES, + XDebuggerUIConstants.ERROR_MESSAGE_ICON, i == 0 ? link : null)); } return messages; } From 1e1351c6dff69e00ddd8c6b02b0457568f968add Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 9 Nov 2010 13:47:36 +0300 Subject: [PATCH 055/257] xdebugger: append hyperlink to the last line of multi-line error message --- .../intellij/xdebugger/impl/ui/tree/nodes/MessageTreeNode.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/MessageTreeNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/MessageTreeNode.java index b3e92d09bf83..d9695c2321be 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/MessageTreeNode.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/MessageTreeNode.java @@ -17,7 +17,6 @@ package com.intellij.xdebugger.impl.ui.tree.nodes; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.SimpleTextAttributes; -import com.intellij.util.ui.EmptyIcon; import com.intellij.xdebugger.XDebuggerBundle; import com.intellij.xdebugger.frame.XDebuggerTreeNodeHyperlink; import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants; @@ -106,7 +105,7 @@ public class MessageTreeNode extends XDebuggerTreeNode { final List lines = StringUtil.split(errorMessage, "\n"); for (int i = 0; i < lines.size(); i++) { messages.add(new MessageTreeNode(tree, parent, lines.get(i), XDebuggerUIConstants.ERROR_MESSAGE_ATTRIBUTES, - XDebuggerUIConstants.ERROR_MESSAGE_ICON, i == 0 ? link : null)); + XDebuggerUIConstants.ERROR_MESSAGE_ICON, i == lines.size() - 1 ? link : null)); } return messages; } From 1979cb37e756851dbac2ddad5ad33739f73bfc47 Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Tue, 9 Nov 2010 16:55:06 +0300 Subject: [PATCH 056/257] fix npe --- .../src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java b/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java index 417dccf4579f..f4ec0419369e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java @@ -709,7 +709,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra IdeFocusManager mgr = getFocusManager(); Runnable r = new Runnable() { public void run() { - myFocusTrackback.restoreFocus(); + if (myFocusTrackback != null) myFocusTrackback.restoreFocus(); myFocusTrackback = null; } }; From c2dd562a83d2d4f357024f161bf178ad098d13ca Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 9 Nov 2010 16:55:19 +0300 Subject: [PATCH 057/257] fix passing selected tab from ProjectSettingsService --- .../openapi/roots/ui/configuration/ModuleEditor.java | 5 +++-- .../roots/ui/configuration/ProjectStructureConfigurable.java | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java index 8af238b834d5..59e25af14f35 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java @@ -60,6 +60,7 @@ import java.util.List; @SuppressWarnings({"AssignmentToStaticFieldFromInstanceMethod"}) public abstract class ModuleEditor implements Place.Navigator, Disposable { + public static final String MODULE_TAB = "moduleTab"; private final Project myProject; private JPanel myGenericSettingsPanel; private ModifiableRootModel myModifiableRootModel; // important: in order to correctly update OrderEntries UI use corresponding proxy for the model @@ -246,12 +247,12 @@ public abstract class ModuleEditor implements Place.Navigator, Disposable { } public ActionCallback navigateTo(@Nullable final Place place, final boolean requestFocus) { - myTabbedPane.setSelectedTitle((String)place.getPath("moduleTab")); + myTabbedPane.setSelectedTitle((String)place.getPath(MODULE_TAB)); return new ActionCallback.Done(); } public void queryPlace(@NotNull final Place place) { - place.putPath("moduleTab", ourSelectedTabName); + place.putPath(MODULE_TAB, ourSelectedTabName); } public static String getSelectedTab(){ diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java index fac45969b2a7..63132c974ee3 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java @@ -359,7 +359,7 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se if (moduleToSelect != null) { final Module module = ModuleManager.getInstance(myProject).findModuleByName(moduleToSelect); assert module != null; - place = place.putPath(ModuleStructureConfigurable.TREE_OBJECT, module); + place = place.putPath(ModuleStructureConfigurable.TREE_OBJECT, module).putPath(ModuleEditor.MODULE_TAB, tab); } return navigateTo(place, requestFocus); } From 822a2d87592b002e7a69cfb643a24d8959c62a5f Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Tue, 9 Nov 2010 17:11:08 +0300 Subject: [PATCH 058/257] deferred icon checks for if element is no logner valid or project disposed --- .../src/com/intellij/psi/impl/ElementBase.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/platform/lang-api/src/com/intellij/psi/impl/ElementBase.java b/platform/lang-api/src/com/intellij/psi/impl/ElementBase.java index f975b8c4d46d..9bde7a523ce1 100644 --- a/platform/lang-api/src/com/intellij/psi/impl/ElementBase.java +++ b/platform/lang-api/src/com/intellij/psi/impl/ElementBase.java @@ -70,6 +70,7 @@ public abstract class ElementBase extends UserDataHolderBase implements Iconable } } + @Nullable private Icon computeIcon(final int flags) { PsiElement psiElement = (PsiElement)this; Icon baseIcon = LastComputedIcon.get(psiElement, flags); @@ -84,12 +85,16 @@ public abstract class ElementBase extends UserDataHolderBase implements Iconable } if (isToDeferIconLoading()) { - return IconDeferrer.getInstance().defer(baseIcon, new ElementIconRequest(psiElement, flags), new Function() { + return IconDeferrer.getInstance().defer(baseIcon, new ElementIconRequest(psiElement, flags), new NullableFunction() { public Icon fun(ElementIconRequest request) { - return computeIconNow(request.getElement(), request.getFlags()); + final PsiElement element = request.getElement(); + if (!element.isValid()) return null; + if (element.getProject().isDisposed()) return null; + return computeIconNow(element, request.getFlags()); } }); } else { + if (!psiElement.isValid()) return null; return computeIconNow(psiElement, flags); } } @@ -98,8 +103,8 @@ public abstract class ElementBase extends UserDataHolderBase implements Iconable return Registry.is("psi.deferIconLoading"); } + @Nullable private Icon computeIconNow(PsiElement element, int flags) { - if (!element.isValid()) return null; final Icon providersIcon = PsiIconUtil.getProvidersIcon(element, flags); if (providersIcon != null) { return providersIcon instanceof RowIcon ? (RowIcon)providersIcon : createLayeredIcon(providersIcon, flags); @@ -166,6 +171,7 @@ public abstract class ElementBase extends UserDataHolderBase implements Iconable } } + @Nullable protected Icon getElementIcon(final int flags) { final PsiElement element = (PsiElement)this; @@ -246,4 +252,4 @@ public abstract class ElementBase extends UserDataHolderBase implements Iconable static { registerIconLayer(FLAGS_LOCKED, Icons.LOCKED_ICON); } -} \ No newline at end of file +} From 8c2746638e98f4aba031984c4480ccca9ff99037 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 9 Nov 2010 17:15:55 +0300 Subject: [PATCH 059/257] provide name for "navigate to source" action on PsiDirectoryNode --- .../impl/nodes/PsiDirectoryNode.java | 28 +++++++++++++++++-- .../com/intellij/pom/NavigatableWithText.java | 3 ++ .../actions/BaseNavigateToSourceAction.java | 9 +++++- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java index 047e12c09453..df2e3249a93e 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java @@ -35,6 +35,7 @@ import com.intellij.openapi.util.Iconable; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.NavigatableWithText; import com.intellij.psi.PsiDirectory; import com.intellij.psi.impl.file.PsiDirectoryFactory; import com.intellij.ui.LayeredIcon; @@ -47,7 +48,7 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.util.Collection; -public class PsiDirectoryNode extends BasePsiNode { +public class PsiDirectoryNode extends BasePsiNode implements NavigatableWithText { public PsiDirectoryNode(Project project, PsiDirectory value, ViewSettings viewSettings) { super(project, value, viewSettings); } @@ -190,15 +191,38 @@ public class PsiDirectoryNode extends BasePsiNode { public void navigate(final boolean requestFocus) { Module module = ModuleUtil.findModuleForPsiElement(getValue()); if (module != null) { - if (ProjectRootsUtil.isModuleContentRoot(getVirtualFile(), getProject())) { + final VirtualFile file = getVirtualFile(); + final Project project = getProject(); + if (ProjectRootsUtil.isModuleContentRoot(file, project)) { ProjectSettingsService.getInstance(myProject).openModuleSettings(module); } + else if (ProjectRootsUtil.isLibraryRoot(file, project)) { + ProjectSettingsService.getInstance(myProject).openModuleLibrarySettings(module); + } else { ProjectSettingsService.getInstance(myProject).openContentEntriesSettings(module); } } } + @Override + public String getNavigateActionText(boolean focusEditor) { + VirtualFile file = getVirtualFile(); + Project project = getProject(); + + if (file != null) { + if (ProjectRootsUtil.isModuleContentRoot(file, project) || + ProjectRootsUtil.isSourceOrTestRoot(file, project)) { + return "Open Module Settings"; + } + if (ProjectRootsUtil.isLibraryRoot(file, project)) { + return "Open Library Settings"; + } + } + + return null; + } + public int getWeight() { return isFQNameShown() ? 70 : 0; } diff --git a/platform/platform-api/src/com/intellij/pom/NavigatableWithText.java b/platform/platform-api/src/com/intellij/pom/NavigatableWithText.java index 57669c1159f7..a9968e592fef 100644 --- a/platform/platform-api/src/com/intellij/pom/NavigatableWithText.java +++ b/platform/platform-api/src/com/intellij/pom/NavigatableWithText.java @@ -15,9 +15,12 @@ */ package com.intellij.pom; +import org.jetbrains.annotations.Nullable; + /** * @author yole */ public interface NavigatableWithText extends Navigatable { + @Nullable String getNavigateActionText(boolean focusEditor); } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/BaseNavigateToSourceAction.java b/platform/platform-impl/src/com/intellij/ide/actions/BaseNavigateToSourceAction.java index 4c85e9465071..14ba0980674e 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/BaseNavigateToSourceAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/BaseNavigateToSourceAction.java @@ -46,13 +46,20 @@ public abstract class BaseNavigateToSourceAction extends AnAction implements Dum event.getPresentation().setEnabled(enabled); } if (target != null && target instanceof NavigatableWithText) { - event.getPresentation().setText(((NavigatableWithText)target).getNavigateActionText(myFocusEditor)); + final String navigateActionText = ((NavigatableWithText)target).getNavigateActionText(myFocusEditor); + if (navigateActionText != null) { + event.getPresentation().setText(navigateActionText); + } + else { + event.getPresentation().setText(getTemplatePresentation().getText()); + } } else { event.getPresentation().setText(getTemplatePresentation().getText()); } } + @Nullable private Navigatable getTarget(final DataContext dataContext) { Navigatable[] navigatables = getNavigatables(dataContext); if (navigatables != null) { From aa6f787a8d8c185f75a11aa9978f367a8c7263b1 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 9 Nov 2010 17:22:40 +0300 Subject: [PATCH 060/257] no need to have two separate module settings actions in the context menu --- .../ide/projectView/impl/nodes/AbstractModuleNode.java | 8 +++++++- resources/src/idea/IdeaActions.xml | 4 ---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/AbstractModuleNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/AbstractModuleNode.java index 3cad5dedf975..2009d454eb16 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/AbstractModuleNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/AbstractModuleNode.java @@ -25,10 +25,11 @@ import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.NavigatableWithText; import com.intellij.ui.SimpleTextAttributes; import org.jetbrains.annotations.NotNull; -public abstract class AbstractModuleNode extends ProjectViewNode { +public abstract class AbstractModuleNode extends ProjectViewNode implements NavigatableWithText { protected AbstractModuleNode(Project project, Module module, ViewSettings viewSettings) { super(project, module, viewSettings); } @@ -84,6 +85,11 @@ public abstract class AbstractModuleNode extends ProjectViewNode { ProjectSettingsService.getInstance(myProject).openModuleSettings(getValue()); } + @Override + public String getNavigateActionText(boolean focusEditor) { + return "Open Module Settings"; + } + public boolean canNavigate() { return true; } diff --git a/resources/src/idea/IdeaActions.xml b/resources/src/idea/IdeaActions.xml index 05130fbc564d..5617e7f3af70 100644 --- a/resources/src/idea/IdeaActions.xml +++ b/resources/src/idea/IdeaActions.xml @@ -382,10 +382,6 @@ - - - - From 9d0e24d7f3e07c72718bbb2b49b0635b9f035d67 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 9 Nov 2010 17:27:44 +0300 Subject: [PATCH 061/257] EA-23238 - SIOOBE: TemplateResource.getMethodBody --- .../tostring/template/TemplateResource.java | 426 +++++++++--------- 1 file changed, 215 insertions(+), 211 deletions(-) diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/template/TemplateResource.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/template/TemplateResource.java index 4ffd7b8ae7f8..d0ff33a96e7a 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/template/TemplateResource.java +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/template/TemplateResource.java @@ -27,246 +27,250 @@ import java.io.Serializable; * the text is stored. */ public class TemplateResource implements Serializable { - private final boolean isDefault; - private String fileName = ""; - private String template = ""; + private final boolean isDefault; + private String fileName = ""; + private String template = ""; - /** - * Constructor. - * - * @param fileName a template filename - * @param template the template velocity body content - */ - public TemplateResource(String fileName, String template) { - this(fileName, template, false); + /** + * Constructor. + * + * @param fileName a template filename + * @param template the template velocity body content + */ + public TemplateResource(String fileName, String template) { + this(fileName, template, false); + } + + public TemplateResource(String fileName, String template, boolean aDefault) { + isDefault = aDefault; + this.fileName = fileName; + this.template = template; + } + + /** + * Bean constructor + */ + public TemplateResource() { + isDefault = false; + } + + public String getTemplate() { + return template; + } + + public void setTemplate(String template) { + this.template = template; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public boolean isDefault() { + return isDefault; + } + + /** + * Get's the javadoc, if any. + * + * @return the javadoc, null if no javadoc. + */ + @Nullable + public String getJavaDoc() { + int i = template.indexOf("*/"); + if (i == -1) { + return null; } - public TemplateResource(String fileName, String template, boolean aDefault) { - isDefault = aDefault; - this.fileName = fileName; - this.template = template; + return template.substring(0, i + 2); + } + + /** + * Get's the method body. + * + * @return the method body. + */ + public String getMethodBody() { + return getMethodBody(template); + } + + @Nullable + private static String getMethodBody(String template) { + String signature = getMethodSignature(template); + String s = StringUtil.after(template, signature); + + if (s == null) { + return null; } - /** - * Bean constructor - */ - public TemplateResource() { - isDefault = false; + // skip the starting and ending { } + final String trimmed = s.trim(); + return trimmed.substring(1, s.length() - 1); + } + + /** + * Gets the method signature + *

+ * public String toString() + */ + public String getMethodSignature() { + return getMethodSignature(template); + } + + private static String getMethodSignature(String template) { + String s = StringUtil.after(template, "*/").trim(); + + StringBuffer signature = new StringBuffer(); + + String[] lines = s.split("\n"); + for (String line : lines) { + line = line.trim(); + if (line.startsWith("@")) { + continue; + } + signature.append(line); + if (line.indexOf("{") > -1) { + break; + } } - public String getTemplate() { - return template; + // remove last { + String result = signature.toString(); + return result.substring(0, result.lastIndexOf("{")); + } + + /** + * Get's the method that this template is for (toString) + */ + public String getTargetMethodName() { + String s = getMethodSignature(); + s = StringUtil.before(s, "("); + int i = s.lastIndexOf(" "); + return s.substring(i).trim(); + } + + /** + * Validates this template to see if its valid for plugin v3.10 or higher. + * + * @return true if valid, false if not + */ + public boolean isValidTemplate() { + return isValidTemplate(template); + } + + /** + * Validates the provided template. + * + * @param template the template to validate. + * @return true if valid, false if not. + */ + public static boolean isValidTemplate(String template) { + template = template.trim(); + + if (template.indexOf("{") == -1) { + return false; } - public void setTemplate(String template) { - this.template = template; + // ending } must be the last character + String s = template.trim(); + if (s.lastIndexOf("}") != s.length() - 1) { + return false; } - public String getFileName() { - return fileName; + if (getMethodSignature(template) == null) { + return false; } - public void setFileName(String fileName) { - this.fileName = fileName; + if (getMethodBody(template) == null) { + return false; } - public boolean isDefault() { - return isDefault; + return true; + } + + /** + * Does the template use annotations? + * + * @return true if so, false if not. + */ + public boolean hasAnnotations() { + return getAnnotations() != null; + } + + /** + * Get's the annotations + * + * @return the annotation, null if does not have. + */ + public String[] getAnnotations() { + String signature = getMethodSignature(); + String javadoc = getJavaDoc(); + String annotations; + if (javadoc != null) { + annotations = StringUtil.middle(template, javadoc, signature); + } + else { + annotations = StringUtil.before(template, signature); } - /** - * Get's the javadoc, if any. - * - * @return the javadoc, null if no javadoc. - */ - @Nullable - public String getJavaDoc() { - int i = template.indexOf("*/"); - if (i == -1) - return null; - - return template.substring(0, i + 2); + if (StringUtil.isEmpty(annotations)) { + return null; } - /** - * Get's the method body. - * - * @return the method body. - */ - public String getMethodBody() { - return getMethodBody(template); + if (annotations.indexOf("@") == -1) { + return null; } - @Nullable - private static String getMethodBody(String template) { - String signature = getMethodSignature(template); - String s = StringUtil.after(template, signature); - - if (s == null) - return null; - - // skip the starting and ending { } - return s.trim().substring(1, s.length() - 1); + // remove first and last \n + annotations = annotations.trim(); + if (annotations.startsWith("\n")) { + annotations = annotations.substring(1); + } + if (annotations.endsWith("\n")) { + annotations = annotations.substring(0, annotations.length() - 1); } - /** - * Gets the method signature - *

- * public String toString() - */ - public String getMethodSignature() { - return getMethodSignature(template); - } + return annotations.split("\n"); + } - private static String getMethodSignature(String template) { - String s = StringUtil.after(template, "*/").trim(); + /** + * Important to return filename only as it is the displayname in the UI. + * + * @return filename for UI. + */ + public String toString() { + return fileName != null ? fileName : template; + } - StringBuffer signature = new StringBuffer(); + public String getName() { + return fileName; + } - String[] lines = s.split("\n"); - for (String line : lines) { - line = line.trim(); - if (line.startsWith("@")) { - continue; - } - signature.append(line); - if (line.indexOf("{") > -1) { - break; - } - } + public void copyFrom(TemplateResource templateResource) { + fileName = templateResource.getFileName(); + template = templateResource.getTemplate(); + } - // remove last { - String result = signature.toString(); - return result.substring(0, result.lastIndexOf("{")); - } + public void setName(String name) { + fileName = name; + } - /** - * Get's the method that this template is for (toString) - */ - public String getTargetMethodName() { - String s = getMethodSignature(); - s = StringUtil.before(s, "("); - int i = s.lastIndexOf(" "); - return s.substring(i).trim(); - } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TemplateResource)) return false; - /** - * Validates this template to see if its valid for plugin v3.10 or higher. - * - * @return true if valid, false if not - */ - public boolean isValidTemplate() { - return isValidTemplate(template); - } + TemplateResource that = (TemplateResource)o; - /** - * Validates the provided template. - * - * @param template the template to validate. - * @return true if valid, false if not. - */ - public static boolean isValidTemplate(String template) { - template = template.trim(); + return fileName.equals(that.fileName) && template.equals(that.template); + } - if (template.indexOf("{") == -1) { - return false; - } - - // ending } must be the last character - String s = template.trim(); - if (s.lastIndexOf("}") != s.length() - 1) { - return false; - } - - if (getMethodSignature(template) == null) { - return false; - } - - if (getMethodBody(template) == null) { - return false; - } - - return true; - } - - /** - * Does the template use annotations? - * - * @return true if so, false if not. - */ - public boolean hasAnnotations() { - return getAnnotations() != null; - } - - /** - * Get's the annotations - * - * @return the annotation, null if does not have. - */ - public String[] getAnnotations() { - String signature = getMethodSignature(); - String javadoc = getJavaDoc(); - String annotations; - if (javadoc != null) { - annotations = StringUtil.middle(template, javadoc, signature); - } else { - annotations = StringUtil.before(template, signature); - } - - if (StringUtil.isEmpty(annotations)) { - return null; - } - - if (annotations.indexOf("@") == -1) { - return null; - } - - // remove first and last \n - annotations = annotations.trim(); - if (annotations.startsWith("\n")) { - annotations = annotations.substring(1); - } - if (annotations.endsWith("\n")) { - annotations = annotations.substring(0, annotations.length()-1); - } - - return annotations.split("\n"); - } - - /** - * Important to return filename only as it is the displayname in the UI. - * @return filename for UI. - */ - public String toString() { - return fileName != null ? fileName : template; - } - - public String getName() { - return fileName; - } - - public void copyFrom(TemplateResource templateResource) { - fileName = templateResource.getFileName(); - template = templateResource.getTemplate(); - } - - public void setName(String name) { - fileName = name; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof TemplateResource)) return false; - - TemplateResource that = (TemplateResource) o; - - return fileName.equals(that.fileName) && template.equals(that.template); - - } - - @Override - public int hashCode() { - return 31 * fileName.hashCode() + template.hashCode(); - } + @Override + public int hashCode() { + return 31 * fileName.hashCode() + template.hashCode(); + } } From a336f1bbc48aea6b33a37a1edf8dae8ad4bb2637 Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 9 Nov 2010 16:29:52 +0300 Subject: [PATCH 062/257] collect statistics for type selected --- .../introduceVariable/IntroduceVariableBase.java | 7 +++++-- .../introduceVariable/ReassignVariableUtil.java | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) 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 b5dc13ba4f83..c8c42e8440f0 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java @@ -462,8 +462,9 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme final IntroduceVariableSettings settings = getSettings(project, editor, expr, occurrences, typeSelectorManager, inFinalContext, hasWriteAccess, validator, choice); if (!settings.isOK()) return; + typeSelectorManager.setAllOccurences(choice != OccurrencesChooser.ReplaceChoice.NO); final RangeMarker exprMarker = editor.getDocument().createRangeMarker(expr.getTextRange()); - final SuggestedNameInfo suggestedName = getSuggestedName(typeSelectorManager.getDefaultType(), expr); + final SuggestedNameInfo suggestedName = getSuggestedName(settings.getSelectedType(), expr); final Runnable runnable = introduce(project, expr, editor, anchorStatement, tempContainer, occurrences, anchorStatementIfAll, settings, variable); CommandProcessor.getInstance().executeCommand( @@ -501,6 +502,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme editor.getCaretModel().moveToOffset(startOffset); } editor.putUserData(ReassignVariableUtil.DECLARATION_KEY, null); + typeSelectorManager.typeSelected(ReassignVariableUtil.getVariableType(declarationStatement)); exprMarker.dispose(); } }); @@ -816,7 +818,8 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme @Override public PsiType getSelectedType() { - return typeSelectorManager.getDefaultType(); + final PsiType selectedType = typeSelectorManager.getTypeSelector().getSelectedType(); + return selectedType != null ? selectedType : typeSelectorManager.getDefaultType(); } @Override diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java index 9e76662587ed..8f7141df44a7 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java @@ -97,7 +97,7 @@ public class ReassignVariableUtil { } @Nullable - private static PsiType getVariableType(@Nullable PsiDeclarationStatement declaration) { + static PsiType getVariableType(@Nullable PsiDeclarationStatement declaration) { if (declaration != null) { final PsiElement[] declaredElements = declaration.getDeclaredElements(); if (declaredElements.length > 0 && declaredElements[0] instanceof PsiVariable) { From 4cd12ba0b26f865d89ff2442ec12330ab9ee1e23 Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 9 Nov 2010 17:17:57 +0300 Subject: [PATCH 063/257] import selected type on insertion --- .../refactoring/introduceVariable/ReassignVariableUtil.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java index 8f7141df44a7..aab01479d103 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java @@ -14,6 +14,7 @@ package com.intellij.refactoring.introduceVariable; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.codeInsight.lookup.PsiTypeLookupItem; import com.intellij.codeInsight.template.Expression; import com.intellij.codeInsight.template.ExpressionContext; import com.intellij.codeInsight.template.TextResult; @@ -167,7 +168,7 @@ public class ReassignVariableUtil { public LookupElement[] calculateLookupItems(ExpressionContext context) { LookupElement[] result = new LookupElement[types.length]; for (int i = 0, typesLength = types.length; i < typesLength; i++) { - result[i] = LookupElementBuilder.create(types[i], types[i].getPresentableText()); + result[i] = PsiTypeLookupItem.createLookupItem(types[i], null); } return result; } From 31551a9aa5c09d7cc1eecdd99bc5a051d67136a9 Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Tue, 9 Nov 2010 17:46:10 +0300 Subject: [PATCH 064/257] IDEA-52423 Bring back option for Run/Debug to pop up configurations --- .../RunnerAndConfigurationSettings.java | 4 +++ .../intellij/execution/ProgramRunnerUtil.java | 2 +- .../com/intellij/execution/RunManagerEx.java | 2 ++ .../ConfigurationSettingsEditorWrapper.java | 31 +++++++++++++------ .../execution/impl/RunManagerImpl.java | 9 ++++++ .../RunnerAndConfigurationSettingsImpl.java | 18 ++++++++++- .../src/messages/ExecutionBundle.properties | 1 + 7 files changed, 56 insertions(+), 11 deletions(-) diff --git a/platform/lang-api/src/com/intellij/execution/RunnerAndConfigurationSettings.java b/platform/lang-api/src/com/intellij/execution/RunnerAndConfigurationSettings.java index 572f7ead1c0d..26a0944f9267 100644 --- a/platform/lang-api/src/com/intellij/execution/RunnerAndConfigurationSettings.java +++ b/platform/lang-api/src/com/intellij/execution/RunnerAndConfigurationSettings.java @@ -52,4 +52,8 @@ public interface RunnerAndConfigurationSettings { void setTemporary(boolean temporary); Factory createFactory(); + + void setEditBeforeRun(boolean b); + + boolean isEditBeforeRun(); } diff --git a/platform/lang-impl/src/com/intellij/execution/ProgramRunnerUtil.java b/platform/lang-impl/src/com/intellij/execution/ProgramRunnerUtil.java index 9b34532b148f..f974986590be 100644 --- a/platform/lang-impl/src/com/intellij/execution/ProgramRunnerUtil.java +++ b/platform/lang-impl/src/com/intellij/execution/ProgramRunnerUtil.java @@ -58,7 +58,7 @@ public class ProgramRunnerUtil { return; } - if (!RunManagerImpl.canRunConfiguration(configuration, executor)) { + if (!RunManagerImpl.canRunConfiguration(configuration, executor) || RunManagerImpl.isEditBeforeRun(configuration)) { final boolean result = RunDialog.editConfiguration(project, configuration, "Edit configuration", executor.getActionName(), executor.getIcon()); if (!result) { return; diff --git a/platform/lang-impl/src/com/intellij/execution/RunManagerEx.java b/platform/lang-impl/src/com/intellij/execution/RunManagerEx.java index fc6b6a24cce6..c2a9d032ae6d 100644 --- a/platform/lang-impl/src/com/intellij/execution/RunManagerEx.java +++ b/platform/lang-impl/src/com/intellij/execution/RunManagerEx.java @@ -48,6 +48,8 @@ public abstract class RunManagerEx extends RunManager { public abstract void setTemporaryConfiguration(RunnerAndConfigurationSettings tempConfiguration); + public abstract void setEditBeforeRun(RunConfiguration settings, boolean edit); + public abstract RunManagerConfig getConfig(); @NotNull diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java b/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java index 53de302b4f2a..efcbd9ef4ea0 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java @@ -18,6 +18,7 @@ package com.intellij.execution.impl; import com.intellij.execution.BeforeRunTask; import com.intellij.execution.BeforeRunTaskProvider; +import com.intellij.execution.ExecutionBundle; import com.intellij.execution.RunnerAndConfigurationSettings; import com.intellij.execution.configurations.RunConfiguration; import com.intellij.execution.configurations.UnknownRunConfiguration; @@ -55,10 +56,12 @@ public class ConfigurationSettingsEditorWrapper extends SettingsEditor, BeforeRunTask> myStepsBeforeLaunch; private final Map, StepBeforeLaunchRow> myStepBeforeLaunchRows = new THashMap, StepBeforeLaunchRow>(); private boolean myStoreProjectConfiguration; + private boolean myEditBeforeRun; private final ConfigurationSettingsEditor myEditor; @@ -78,7 +81,7 @@ public class ConfigurationSettingsEditorWrapper extends SettingsEditor[] providers = Extensions.getExtensions(BeforeRunTaskProvider.EXTENSION_POINT_NAME, runConfiguration.getProject()); myStepsPanel.removeAll(); - if (providers.length == 0 || runConfiguration instanceof UnknownRunConfiguration) { + if (runConfiguration instanceof UnknownRunConfiguration) { myStepsPanel.setVisible(false); } else { @@ -92,17 +95,25 @@ public class ConfigurationSettingsEditorWrapper extends SettingsEditor, BeforeRunTask> getStepsBeforeLaunch() { 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 30f57223b6d9..329392e2ed1e 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java @@ -619,6 +619,15 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, setActiveConfiguration(tempConfiguration); } + public static boolean isEditBeforeRun(@NotNull final RunnerAndConfigurationSettings configuration) { + return configuration.isEditBeforeRun(); + } + + public void setEditBeforeRun(@NotNull final RunConfiguration configuration, final boolean edit) { + final RunnerAndConfigurationSettings settings = getSettings(configuration); + if (settings != null) settings.setEditBeforeRun(edit); + } + public void setActiveConfiguration(final RunnerAndConfigurationSettings configuration) { setSelectedConfiguration(configuration); } diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.java index 94de17906a01..18730145d1f3 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.java @@ -57,6 +57,9 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C protected static final String DUMMY_ELEMENT_NANE = "dummy"; @NonNls private static final String TEMPORARY_ATTRIBUTE = "temporary"; + @NonNls + private static final String EDIT_BEFORE_RUN = "editBeforeRun"; + /** for compatibility */ @NonNls @@ -73,6 +76,7 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C private List myUnloadedConfigurationPerRunnerSettings = null; private boolean myTemporary; + private boolean myEditBeforeRun; public RunnerAndConfigurationSettingsImpl(RunManagerImpl manager) { myManager = manager; @@ -122,6 +126,16 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C return myConfiguration.getName(); } + @Override + public void setEditBeforeRun(boolean b) { + myEditBeforeRun = b; + } + + @Override + public boolean isEditBeforeRun() { + return myEditBeforeRun; + } + @Nullable private ConfigurationFactory getFactory(final Element element) { final String typeName = element.getAttributeValue(CONFIGURATION_TYPE_ATTRIBUTE); @@ -130,9 +144,9 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C } public void readExternal(Element element) throws InvalidDataException { - myIsTemplate = Boolean.valueOf(element.getAttributeValue(TEMPLATE_FLAG_ATTRIBUTE)).booleanValue(); myTemporary = Boolean.valueOf(element.getAttributeValue(TEMPORARY_ATTRIBUTE)).booleanValue() || TEMP_CONFIGURATION.equals(element.getName()); + myEditBeforeRun = Boolean.valueOf(element.getAttributeValue(EDIT_BEFORE_RUN)).booleanValue(); final ConfigurationFactory factory = getFactory(element); if (factory == null) return; @@ -192,6 +206,8 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C } element.setAttribute(CONFIGURATION_TYPE_ATTRIBUTE, factory.getType().getId()); element.setAttribute(FACTORY_NAME_ATTRIBUTE, factory.getName()); + + if (isEditBeforeRun()) element.setAttribute(EDIT_BEFORE_RUN, String.valueOf(true)); if (myTemporary) { element.setAttribute(TEMPORARY_ATTRIBUTE, Boolean.toString(myTemporary)); } diff --git a/platform/platform-resources-en/src/messages/ExecutionBundle.properties b/platform/platform-resources-en/src/messages/ExecutionBundle.properties index 31c03b502121..cc8ae5dda7d5 100644 --- a/platform/platform-resources-en/src/messages/ExecutionBundle.properties +++ b/platform/platform-resources-en/src/messages/ExecutionBundle.properties @@ -301,3 +301,4 @@ export.test.results.open.browser=O&pen exported file in browser export.test.results.dialog.title=Export Test Results export.test.results.output.path.empty=Output path is empty export.test.results.output.filename.empty=Output file name is empty +configuration.edit.before.run=Show settings From d9c128e9bd75284f89f498de304148ad76bfd5fd Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 9 Nov 2010 18:03:18 +0300 Subject: [PATCH 065/257] IDEA-60591 (use correct yjpagent on 64-bit Linux in IDEA) --- bin/nix/idea.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 bin/nix/idea.sh diff --git a/bin/nix/idea.sh b/bin/nix/idea.sh old mode 100644 new mode 100755 index 941b392455aa..6b19f0819c4e --- a/bin/nix/idea.sh +++ b/bin/nix/idea.sh @@ -84,7 +84,7 @@ fi REQUIRED_JVM_ARGS="-Xbootclasspath/a:../lib/boot.jar $IDEA_PROPERTIES_PROPERTY $REQUIRED_JVM_ARGS" JVM_ARGS=`tr '\n' ' ' < "$IDEA_VM_OPTIONS"` -JVM_ARGS="$JVM_ARGS $REQUIRED_JVM_ARGS" +JVM_ARGS=`eval echo $JVM_ARGS $REQUIRED_JVM_ARGS` CLASSPATH=../lib/bootstrap.jar CLASSPATH=$CLASSPATH:../lib/util.jar From c6e8dece2de038fd7ef5fbc37f639414d42e7293 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 9 Nov 2010 18:23:20 +0300 Subject: [PATCH 066/257] Exit application startup scripts if no JDK was found (Unix) --- bin/nix/idea.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/bin/nix/idea.sh b/bin/nix/idea.sh index 6b19f0819c4e..cf3b52de4e7e 100755 --- a/bin/nix/idea.sh +++ b/bin/nix/idea.sh @@ -26,7 +26,11 @@ if [ -z "$IDEA_JDK" ]; then fi if [ -z "$IDEA_JDK" ]; then echo ERROR: cannot start IntelliJ IDEA. - echo No JDK found to run IDEA. Please validate either IDEA_JDK or JDK_HOME points to valid JDK installation + echo No JDK found to run IDEA. Please validate either IDEA_JDK, JDK_HOME or JAVA_HOME points to valid JDK installation. + echo + echo Press Enter to continue. + read IGNORE + exit 1 fi fi @@ -36,7 +40,7 @@ grep 'OpenJDK' $VERSION_LOG OPEN_JDK=$? grep '64-Bit' $VERSION_LOG BITS=$? -rm /tmp/java.version.log +rm $VERSION_LOG if [ $OPEN_JDK -eq 0 ]; then echo WARNING: You are launching IDE using OpenJDK Java runtime echo From 626aa548ba6d48cd7fdeb77a1b63e46ac233caca Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 9 Nov 2010 19:06:08 +0300 Subject: [PATCH 067/257] count on Show Colors option on the start --- .../intellij/openapi/vcs/actions/AnnotationFieldGutter.java | 2 +- .../openapi/vcs/actions/ShowAnnotationColorsAction.java | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotationFieldGutter.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotationFieldGutter.java index 6f3f99d9e8b7..55a54738ec39 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotationFieldGutter.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotationFieldGutter.java @@ -47,7 +47,7 @@ class AnnotationFieldGutter implements ActiveAnnotationGutter { private final AnnotationListener myListener; private final boolean myIsGutterAction; private Map myColorScheme; - private boolean myShowBg = true; + private boolean myShowBg = ShowAnnotationColorsAction.isColorsEnabled(); private boolean myShowAdditionalInfo = false; AnnotationFieldGutter(FileAnnotation annotation, Editor editor, LineAnnotationAspect aspect, final TextAnnotationPresentation presentation, Map colorScheme) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/ShowAnnotationColorsAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/ShowAnnotationColorsAction.java index 5001368ac0f8..d222d9499e4f 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/ShowAnnotationColorsAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/ShowAnnotationColorsAction.java @@ -35,7 +35,7 @@ public class ShowAnnotationColorsAction extends ToggleAction { @Override public boolean isSelected(AnActionEvent e) { - return PropertiesComponent.getInstance().getBoolean(KEY, true); + return isColorsEnabled(); } @Override @@ -46,4 +46,8 @@ public class ShowAnnotationColorsAction extends ToggleAction { } myGutter.revalidateMarkup(); } + + public static boolean isColorsEnabled() { + return PropertiesComponent.getInstance().getBoolean(KEY, true); + } } From 3183bbbc81b9bb9e21d9fb8b9b43fa699d26f905 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Tue, 9 Nov 2010 19:27:29 +0300 Subject: [PATCH 068/257] IDEA-60781 After formatting cursor jumps from indented position to beginning of the line. Caret location is restored according to its position before formatting instead of indent offset --- .../codeStyle/CodeStyleManagerImpl.java | 37 +++++-------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java index 90c00162f75e..dcdc78135e83 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java @@ -154,7 +154,8 @@ public class CodeStyleManagerImpl extends CodeStyleManager { // } // Formatter removes such white spaces, i.e. keeps only line feed symbol. But we want to preserve caret position then. // So, we check if it should be preserved and restore it after formatting if necessary - boolean fixCaretPosition = false; + int visualColumnToRestore = -1; + if (editor != null) { Document document = editor.getDocument(); int caretOffset = editor.getCaretModel().getOffset(); @@ -162,7 +163,7 @@ public class CodeStyleManagerImpl extends CodeStyleManager { CharSequence text = document.getCharsSequence(); int caretLine = document.getLineNumber(caretOffset); int lineStartOffset = document.getLineStartOffset(caretLine); - fixCaretPosition = true; + boolean fixCaretPosition = true; for (int i = caretOffset; i>= lineStartOffset; i--) { char c = text.charAt(i); if (c != ' ' && c != '\t' && c != '\n') { @@ -170,6 +171,9 @@ public class CodeStyleManagerImpl extends CodeStyleManager { break; } } + if (fixCaretPosition) { + visualColumnToRestore = editor.getCaretModel().getVisualPosition().column; + } } @@ -190,38 +194,15 @@ public class CodeStyleManagerImpl extends CodeStyleManager { formatToEnd ? file.getTextLength() : endElement.getTextRange().getEndOffset())); } - if (!fixCaretPosition) { + if (visualColumnToRestore < 0) { return; } CaretModel caretModel = editor.getCaretModel(); - String indent = getLineIndent(file, caretModel.getOffset()); - if (indent == null) { - return; - } - int tabSize = getSettings().getTabSize(file.getFileType()); - int indentColumn = indentInVisualColumns(indent, tabSize); VisualPosition position = caretModel.getVisualPosition(); - if (indentColumn != position.column) { - caretModel.moveToVisualPosition(new VisualPosition(position.line, indentColumn)); + if (visualColumnToRestore != position.column) { + caretModel.moveToVisualPosition(new VisualPosition(position.line, visualColumnToRestore)); } } - - private static int indentInVisualColumns(String indent, int tabSize) { - if (tabSize <= 1) { - return indent.length(); - } - int result = 0; - for (int i = 0; i < indent.length(); i++) { - char c = indent.charAt(i); - if (c == '\t') { - result += tabSize - result % tabSize; - } - else { - result++; - } - } - return result; - } private PsiElement reformatRangeImpl(final PsiElement element, final int startOffset, From 2fde612208228f5d25cde3e0ddc1f0f77a6cd66b Mon Sep 17 00:00:00 2001 From: "Rustam.Vishnyakov" Date: Tue, 9 Nov 2010 19:05:00 +0300 Subject: [PATCH 069/257] Add JavaScript files to the library from a specified directory, file type (source/compact) autodetection --- .../LangScriptingContextProvider.java | 5 ++- .../ui/EditLibraryDialog.form | 28 ++++++++----- .../ui/EditLibraryDialog.java | 42 +++++++++++++++---- 3 files changed, 55 insertions(+), 20 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/LangScriptingContextProvider.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/LangScriptingContextProvider.java index d7f7c9d9c4ff..957ea71c02ad 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/LangScriptingContextProvider.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/LangScriptingContextProvider.java @@ -16,10 +16,9 @@ package com.intellij.ide.scriptingContext; import com.intellij.lang.Language; -import com.intellij.openapi.extensions.ExtensionPointName; -import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.libraries.LibraryType; +import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; /** @@ -36,4 +35,6 @@ public abstract class LangScriptingContextProvider { public abstract ScriptingLibraryMappings getLibraryMappings(Project project); + public abstract boolean isCompact(VirtualFile file); + } diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.form b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.form index c1186386820d..803ac485f05e 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.form +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.form @@ -3,7 +3,7 @@ - + @@ -47,7 +47,7 @@ - + @@ -70,19 +70,27 @@ - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.java index 018a01e4637d..f83dc4dfef9e 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.java @@ -50,6 +50,7 @@ public class EditLibraryDialog extends DialogWrapper { private JButton myAddFileButton; private JButton myRemoveFileButton; private JBTable myFileTable; + private JButton myAttachFromButton; private Project myProject; private FileTableModel myFileTableModel; private VirtualFile mySelectedFile; @@ -65,6 +66,14 @@ public class EditLibraryDialog extends DialogWrapper { addFiles(); } }); + + myAttachFromButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + attachFromDirectory(); + } + }); + myFileTableModel = new FileTableModel(); myFileTable.setModel(myFileTableModel); @@ -135,14 +144,31 @@ public class EditLibraryDialog extends DialogWrapper { FileChooserDescriptor chooserDescriptor = new LibFileChooserDescriptor(); VirtualFile[] files = FileChooser.chooseFiles(myProject, chooserDescriptor); if (files.length == 1 && files[0] != null) { - myFileTableModel.addFile(files[0], false); + myFileTableModel.addFile(files[0]); + } + } + + private void attachFromDirectory() { + FileChooserDescriptor chooserDescriptor = new FileChooserDescriptor(false, true, false, false, false, false); + chooserDescriptor.setTitle("Select a directory to attach files from"); //TODO Move to resources + VirtualFile[] files = FileChooser.chooseFiles(myProject, chooserDescriptor); + if (files.length == 1 && files[0] != null) { + VirtualFile chosenDir = files[0]; + if (chosenDir.isDirectory() && chosenDir.isValid()) { + if (myLibName.getText().isEmpty()) myLibName.setText(chosenDir.getName()); + for (VirtualFile file : chosenDir.getChildren()) { + if (file.isValid() && !file.isDirectory() && myProvider.acceptsExtension(file.getExtension())) { + myFileTableModel.addFile(file); + } + } + } } } private class LibFileChooserDescriptor extends FileChooserDescriptor { public LibFileChooserDescriptor() { super (true, false, false, true, false, false); - setTitle("Select library file"); + setTitle("Select library file"); //TODO Move to resources } @Override @@ -158,14 +184,14 @@ public class EditLibraryDialog extends DialogWrapper { } } - private static class FileTableModel extends AbstractTableModel { + private class FileTableModel extends AbstractTableModel { @Override public String getColumnName(int column) { switch(column) { case FILE_LOCATION_COL: - return "Location"; - case FILE_TYPE_COL: + return "Location"; //TODO Move to resources + case FILE_TYPE_COL: //TODO Move to resources return "Type"; } return ""; @@ -182,9 +208,9 @@ public class EditLibraryDialog extends DialogWrapper { private ArrayList myFiles = new ArrayList(); private HashSet myCompactFiles = new HashSet(); - public void addFile(VirtualFile file, boolean isCompact) { + public void addFile(VirtualFile file) { myFiles.add(file); - if (isCompact) { + if (myProvider.isCompact(file)) { myCompactFiles.add(file); } fireTableDataChanged(); @@ -286,7 +312,7 @@ public class EditLibraryDialog extends DialogWrapper { @Override protected void doOKAction() { if (!isLibNameValid(myLibName.getText())) { - Messages.showErrorDialog(myProject, "Invalid library name", "Error"); + Messages.showErrorDialog(myProject, "Invalid library name", "Error"); //TODO Move to resources return; } super.doOKAction(); From 696f4dfd9b4e6c2ed5fd36558e52f30fba764d12 Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Tue, 9 Nov 2010 22:22:43 +0300 Subject: [PATCH 070/257] IDEA-25623 validate mandatory attributes in the layout definition --- .../android/dom/AndroidDomExtender.java | 111 +++++++++++++----- plugins/android/testData/dom/layout/hl.xml | 4 +- plugins/android/testData/dom/layout/idh.xml | 13 +- .../testData/dom/layout/layoutAttrs.xml | 10 ++ .../testData/dom/layout/primValues.xml | 7 +- .../android/testData/dom/layout/systemRes.xml | 11 +- plugins/android/testData/dom/layout/vcr1.xml | 3 +- .../android/dom/Android11LayoutDomTest.java | 2 +- .../android/dom/AndroidLayoutDomTest.java | 4 + 9 files changed, 118 insertions(+), 47 deletions(-) create mode 100644 plugins/android/testData/dom/layout/layoutAttrs.xml diff --git a/plugins/android/src/org/jetbrains/android/dom/AndroidDomExtender.java b/plugins/android/src/org/jetbrains/android/dom/AndroidDomExtender.java index 83b796d834c1..b59163d81938 100644 --- a/plugins/android/src/org/jetbrains/android/dom/AndroidDomExtender.java +++ b/plugins/android/src/org/jetbrains/android/dom/AndroidDomExtender.java @@ -25,10 +25,7 @@ import com.intellij.psi.xml.XmlAttribute; import com.intellij.psi.xml.XmlTag; import com.intellij.util.ArrayUtil; import com.intellij.util.Processor; -import com.intellij.util.xml.Converter; -import com.intellij.util.xml.DomElement; -import com.intellij.util.xml.GenericAttributeValue; -import com.intellij.util.xml.XmlName; +import com.intellij.util.xml.*; import com.intellij.util.xml.reflect.DomExtender; import com.intellij.util.xml.reflect.DomExtension; import com.intellij.util.xml.reflect.DomExtensionsRegistrar; @@ -60,6 +57,7 @@ import org.jetbrains.android.util.AndroidUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.*; @@ -93,6 +91,7 @@ public class AndroidDomExtender extends DomExtender { @NotNull StyleableDefinition[] styleables, @Nullable String namespace, DomExtensionsRegistrar registrar, + MyAttributeProcessor processor, String... skipNames) { Set skippedAttrSet = new HashSet(); Collections.addAll(skippedAttrSet, skipNames); @@ -107,7 +106,7 @@ public class AndroidDomExtender extends DomExtender { String attrName = attrDef.getName(); if (!skippedAttrSet.contains(attrName)) { skippedAttrSet.add(attrName); - registerAttribute(attrDef, namespace, registrar); + registerAttribute(attrDef, namespace, registrar, processor, element); } } } @@ -120,7 +119,15 @@ public class AndroidDomExtender extends DomExtender { return formats.size() > 1; } - private static void registerAttribute(@NotNull AttributeDefinition attrDef, String namespaceKey, DomExtensionsRegistrar registrar) { + private interface MyAttributeProcessor { + void process(@NotNull XmlName attrName, @NotNull DomExtension extension, @NotNull DomElement element); + } + + private static void registerAttribute(@NotNull AttributeDefinition attrDef, + String namespaceKey, + DomExtensionsRegistrar registrar, + @Nullable MyAttributeProcessor processor, + @NotNull DomElement element) { XmlName xmlName = new XmlName(attrDef.getName(), namespaceKey); Set formats = attrDef.getFormats(); Class valueClass = formats.size() == 1 ? getValueClass(formats.iterator().next()) : String.class; @@ -130,14 +137,18 @@ public class AndroidDomExtender extends DomExtender { if (converter != null) { extension.setConverter(converter, mustBeSoft(converter, attrDef.getFormats())); } + if (processor != null) { + processor.process(xmlName, extension, element); + } } protected static void registerAttributes(AndroidFacet facet, DomElement element, @NotNull String[] styleableNames, - DomExtensionsRegistrar registrar) { - registerAttributes(facet, element, styleableNames, null, registrar); - registerAttributes(facet, element, styleableNames, SYSTEM_RESOURCE_PACKAGE, registrar); + DomExtensionsRegistrar registrar, + MyAttributeProcessor processor) { + registerAttributes(facet, element, styleableNames, null, registrar, processor); + registerAttributes(facet, element, styleableNames, SYSTEM_RESOURCE_PACKAGE, registrar, processor); } private static StyleableDefinition[] getStyleables(@NotNull AttributeDefinitions definitions, @NotNull String[] names) { @@ -157,7 +168,7 @@ public class AndroidDomExtender extends DomExtender { @Nullable String resPackage, DomExtensionsRegistrar registrar, String... skipNames) { - registerAttributes(facet, element, new String[]{styleableName}, resPackage, registrar, skipNames); + registerAttributes(facet, element, new String[]{styleableName}, resPackage, registrar, null, skipNames); } protected static void registerAttributes(AndroidFacet facet, @@ -165,6 +176,7 @@ public class AndroidDomExtender extends DomExtender { @NotNull String[] styleableNames, @Nullable String resPackage, DomExtensionsRegistrar registrar, + MyAttributeProcessor processor, String... skipNames) { ResourceManager manager = facet.getResourceManager(resPackage); if (manager == null) return; @@ -172,7 +184,7 @@ public class AndroidDomExtender extends DomExtender { if (attrDefs == null) return; StyleableDefinition[] styleables = getStyleables(attrDefs, styleableNames); String namespace = getNamespaceKeyByResourcePackage(facet, resPackage); - registerStyleableAttributes(element, styleables, namespace, registrar, skipNames); + registerStyleableAttributes(element, styleables, namespace, registrar, processor, skipNames); } @NotNull @@ -195,11 +207,12 @@ public class AndroidDomExtender extends DomExtender { protected static void registerAttributesForClassAndSuperclasses(AndroidFacet facet, DomElement element, PsiClass c, - DomExtensionsRegistrar registrar) { + DomExtensionsRegistrar registrar, + MyAttributeProcessor processor) { while (c != null) { String styleableName = c.getName(); if (styleableName != null) { - registerAttributes(facet, element, new String[]{styleableName}, registrar); + registerAttributes(facet, element, new String[]{styleableName}, registrar, processor); } c = getSuperclass(c); } @@ -241,7 +254,7 @@ public class AndroidDomExtender extends DomExtender { PsiClass c = prefClassMap.get(prefClassName); // register attributes by preference class - registerAttributesForClassAndSuperclasses(facet, element, c, registrar); + registerAttributesForClassAndSuperclasses(facet, element, c, registrar, null); //register attributes by widget String suffix = "Preference"; @@ -249,7 +262,7 @@ public class AndroidDomExtender extends DomExtender { String widgetClassName = prefClassName.substring(0, prefClassName.length() - suffix.length()); Map viewClassMap = getViewClassMap(facet); PsiClass widgetClass = viewClassMap.get(widgetClassName); - registerAttributesForClassAndSuperclasses(facet, element, widgetClass, registrar); + registerAttributesForClassAndSuperclasses(facet, element, widgetClass, registrar, null); } if (c != null && isPreference(prefClassMap, c)) { @@ -277,7 +290,7 @@ public class AndroidDomExtender extends DomExtender { final String styleableName = AndroidAnimationUtils.getStyleableNameByTagName(tagName); PsiClass c = facet.findClass(AndroidUtils.ANIMATION_PACKAGE + '.' + styleableName); if (c != null) { - registerAttributesForClassAndSuperclasses(facet, element, c, registrar); + registerAttributesForClassAndSuperclasses(facet, element, c, registrar, null); } else { registerAttributes(facet, element, styleableName, SYSTEM_RESOURCE_PACKAGE, registrar); @@ -303,33 +316,70 @@ public class AndroidDomExtender extends DomExtender { return ArrayUtil.toStringArray(names); } - private static void registerLayoutAttributes(AndroidFacet facet, DomElement element, XmlTag tag, DomExtensionsRegistrar registrar) { + private static void registerLayoutAttributes(AndroidFacet facet, + DomElement element, + XmlTag tag, + DomExtensionsRegistrar registrar, + MyAttributeProcessor processor) { XmlTag parentTag = tag.getParentTag(); Map map = getViewClassMap(facet); if (parentTag != null) { PsiClass c = map.get(parentTag.getName()); while (c != null) { - registerLayoutAttributes(facet, element, c, registrar); + registerLayoutAttributes(facet, element, c, registrar, processor); c = getSuperclass(c); } } else { for (String className : map.keySet()) { PsiClass c = map.get(className); - registerLayoutAttributes(facet, element, c, registrar); + registerLayoutAttributes(facet, element, c, registrar, processor); } } } - private static void registerLayoutAttributes(AndroidFacet facet, DomElement element, PsiClass c, DomExtensionsRegistrar registrar) { + private static void registerLayoutAttributes(AndroidFacet facet, + DomElement element, + PsiClass c, + DomExtensionsRegistrar registrar, + MyAttributeProcessor processor) { String styleableName = c.getName(); if (styleableName != null) { for (String suf : LAYOUT_ATTRIBUTES_SUFS) { - registerAttributes(facet, element, new String[]{styleableName + suf}, registrar); + registerAttributes(facet, element, new String[]{styleableName + suf}, registrar, processor); } } } + private static final MyAttributeProcessor ourLayoutAttrsProcessor = new MyAttributeProcessor() { + @Override + public void process(@NotNull XmlName attrName, @NotNull DomExtension extension, @NotNull DomElement element) { + if (element instanceof LayoutViewElement && + SdkConstants.NS_RESOURCES.equals(attrName.getNamespaceKey()) && + ("layout_width".equals(attrName.getLocalName()) || "layout_height".equals(attrName.getLocalName()))) { + extension.addCustomAnnotation(new MyRequired()); + } + } + }; + + private static class MyRequired implements Required { + public boolean value() { + return true; + } + + public boolean nonEmpty() { + return true; + } + + public boolean identifier() { + return false; + } + + public Class annotationType() { + return Required.class; + } + } + public static void registerExtensionsForLayout(AndroidFacet facet, XmlTag tag, LayoutElement element, @@ -339,20 +389,20 @@ public class AndroidDomExtender extends DomExtender { if (element instanceof Include) { for (String className : map.keySet()) { PsiClass c = map.get(className); - registerLayoutAttributes(facet, element, c, registrar); + registerLayoutAttributes(facet, element, c, registrar, ourLayoutAttrsProcessor); } return; } String tagName = tag.getName(); if (!tagName.equals("view")) { PsiClass c = map.get(tagName); - registerAttributesForClassAndSuperclasses(facet, element, c, registrar); + registerAttributesForClassAndSuperclasses(facet, element, c, registrar, ourLayoutAttrsProcessor); } else { String[] styleableNames = getClassNames(map.values()); - registerAttributes(facet, element, styleableNames, registrar); + registerAttributes(facet, element, styleableNames, registrar, ourLayoutAttrsProcessor); } - registerLayoutAttributes(facet, element, tag, registrar); + registerLayoutAttributes(facet, element, tag, registrar, ourLayoutAttrsProcessor); for (String viewClassName : map.keySet()) { PsiClass viewClass = map.get(viewClassName); @@ -376,7 +426,7 @@ public class AndroidDomExtender extends DomExtender { if (attrDefs == null) return; StyleableDefinition styleable = attrDefs.getStyleableByName(styleableName); if (styleable == null) return; - registerStyleableAttributes(element, new StyleableDefinition[]{styleable}, SdkConstants.NS_RESOURCES, registrar, skipNames); + registerStyleableAttributes(element, new StyleableDefinition[]{styleable}, SdkConstants.NS_RESOURCES, registrar, null, skipNames); Set subtagSet = new HashSet(); Collections.addAll(subtagSet, AndroidManifestUtils.getStaticallyDefinedSubtags(element)); @@ -395,7 +445,7 @@ public class AndroidDomExtender extends DomExtender { AndroidFacet facet = AndroidFacet.getInstance(element); if (facet == null) return; XmlTag tag = element.getXmlTag(); - registerExistingAttributes(facet, tag, registrar); + registerExistingAttributes(facet, tag, registrar, element); String tagName = tag.getName(); Set registeredSubtags = new HashSet(); if (element instanceof ManifestElement) { @@ -449,7 +499,10 @@ public class AndroidDomExtender extends DomExtender { } } - private static void registerExistingAttributes(AndroidFacet facet, XmlTag tag, DomExtensionsRegistrar registrar) { + private static void registerExistingAttributes(AndroidFacet facet, + XmlTag tag, + DomExtensionsRegistrar registrar, + AndroidDomElement element) { XmlAttribute[] attrs = tag.getAttributes(); for (XmlAttribute attr : attrs) { String localName = attr.getLocalName(); @@ -460,7 +513,7 @@ public class AndroidDomExtender extends DomExtender { attrDef = new AttributeDefinition(localName); } String namespace = attr.getNamespace(); - registerAttribute(attrDef, namespace.length() > 0 ? namespace : null, registrar); + registerAttribute(attrDef, namespace.length() > 0 ? namespace : null, registrar, null, element); } } } diff --git a/plugins/android/testData/dom/layout/hl.xml b/plugins/android/testData/dom/layout/hl.xml index bd8e619920e4..eee46b437863 100644 --- a/plugins/android/testData/dom/layout/hl.xml +++ b/plugins/android/testData/dom/layout/hl.xml @@ -18,8 +18,8 @@ android:text="@string/animation_1_instructions" /> - - + + diff --git a/plugins/android/testData/dom/layout/idh.xml b/plugins/android/testData/dom/layout/idh.xml index 4883d1f0df7e..734c01197d87 100644 --- a/plugins/android/testData/dom/layout/idh.xml +++ b/plugins/android/testData/dom/layout/idh.xml @@ -1,7 +1,8 @@ - -