From 7ded9ace3adc713240561089739f9d194d338ff8 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Thu, 15 Mar 2012 14:39:08 +0400 Subject: [PATCH 01/21] Revert "GitRootConverter: cache detected roots" Reason: detect nested folders can't be implemented easily - need change in ModuleDefaultVcsRootPolicy, not now. More commits to be reverted. This reverts commit 9a7b237aebedfe06df9c4957cd0ee0d5c5e5e026. --- .../src/git4idea/GitRootConverter.java | 25 ++++------------ .../git4idea/repo/GitRepositoryManager.java | 4 --- .../src/git4idea/roots/GitRootChecker.java | 2 +- .../git4idea/roots/GitRootErrorsFinder.java | 4 +-- .../roots/GitRootProblemNotifier.java | 24 ++++++--------- .../src/git4idea/roots/GitRootScanner.java | 6 +--- .../src/git4idea/roots/GitRootsListener.java | 29 ------------------- .../roots/GitRootErrorsFinderTest.groovy | 3 +- 8 files changed, 19 insertions(+), 78 deletions(-) delete mode 100644 plugins/git4idea/src/git4idea/roots/GitRootsListener.java diff --git a/plugins/git4idea/src/git4idea/GitRootConverter.java b/plugins/git4idea/src/git4idea/GitRootConverter.java index 862ea923ac68..1e29fde47f51 100644 --- a/plugins/git4idea/src/git4idea/GitRootConverter.java +++ b/plugins/git4idea/src/git4idea/GitRootConverter.java @@ -21,50 +21,40 @@ import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.VcsDirectoryMapping; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.HashSet; -import git4idea.repo.GitRepositoryManager; +import git4idea.roots.GitRootDetectInfo; import git4idea.roots.GitRootDetector; -import git4idea.roots.GitRootsListener; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.ArrayList; -import java.util.Collection; import java.util.List; /** * Given VFS content roots, filters them and returns only those, which are actual Git roots. */ -public class GitRootConverter implements AbstractVcs.RootsConvertor, GitRootsListener { +public class GitRootConverter implements AbstractVcs.RootsConvertor { @NotNull private final Project myProject; @NotNull private final PlatformFacade myPlatformFacade; - @Nullable private Collection myDetectedRoots; - public GitRootConverter(@NotNull Project project, @NotNull PlatformFacade facade) { myProject = project; myPlatformFacade = facade; - myProject.getMessageBus().connect().subscribe(GitRepositoryManager.GIT_ROOTS_CHANGE, this); } @NotNull public List convertRoots(@NotNull List result) { - if (myDetectedRoots == null) { - myDetectedRoots = new GitRootDetector(myProject, myPlatformFacade).detect().getRoots(); - } + GitRootDetectInfo detectInfo = new GitRootDetector(myProject, myPlatformFacade).detect(); ArrayList roots = new ArrayList(); if (hasProjectMapping()) { - roots.addAll(myDetectedRoots); + roots.addAll(detectInfo.getRoots()); } HashSet listed = new HashSet(); for (VirtualFile f : result) { VirtualFile r = GitUtil.gitRootOrNull(f); if (r != null && listed.add(r)) { - if (!roots.contains(r)) { - roots.add(r); - } + roots.add(r); } } return roots; @@ -79,9 +69,4 @@ public class GitRootConverter implements AbstractVcs.RootsConvertor, GitRootsLis return false; } - @Override - public void gitRootsChanged(Collection roots) { - myDetectedRoots = roots; - } - } diff --git a/plugins/git4idea/src/git4idea/repo/GitRepositoryManager.java b/plugins/git4idea/src/git4idea/repo/GitRepositoryManager.java index e1c95222d77b..e75e8583e8d3 100644 --- a/plugins/git4idea/src/git4idea/repo/GitRepositoryManager.java +++ b/plugins/git4idea/src/git4idea/repo/GitRepositoryManager.java @@ -16,8 +16,6 @@ package git4idea.repo; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.messages.Topic; -import git4idea.roots.GitRootsListener; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -29,8 +27,6 @@ import java.util.List; */ public interface GitRepositoryManager { - Topic GIT_ROOTS_CHANGE = Topic.create("Git Roots change", GitRootsListener.class); - /** * Returns the {@link GitRepository} which tracks the Git repository located in the given directory, * or {@code null} if the given file is not a Git root known to this {@link com.intellij.openapi.project.Project}. diff --git a/plugins/git4idea/src/git4idea/roots/GitRootChecker.java b/plugins/git4idea/src/git4idea/roots/GitRootChecker.java index bfd046344ea4..ec5e97cf4efe 100644 --- a/plugins/git4idea/src/git4idea/roots/GitRootChecker.java +++ b/plugins/git4idea/src/git4idea/roots/GitRootChecker.java @@ -35,7 +35,7 @@ public class GitRootChecker implements VcsRootChecker { private final boolean myProjectMappingIsInvalid; public GitRootChecker(@NotNull Project project, @NotNull PlatformFacade platformFacade) { - myErrors = new GitRootErrorsFinder(project, platformFacade).find(new GitRootDetector(project, platformFacade).detect()); + myErrors = new GitRootErrorsFinder(project, platformFacade).find(); myProjectMappingIsInvalid = isProjectMappingInvalid(); } diff --git a/plugins/git4idea/src/git4idea/roots/GitRootErrorsFinder.java b/plugins/git4idea/src/git4idea/roots/GitRootErrorsFinder.java index 1ca0ffb9053d..8f68c17ef72f 100644 --- a/plugins/git4idea/src/git4idea/roots/GitRootErrorsFinder.java +++ b/plugins/git4idea/src/git4idea/roots/GitRootErrorsFinder.java @@ -48,9 +48,9 @@ public class GitRootErrorsFinder { } @NotNull - public Collection find(@NotNull GitRootDetectInfo rootDetectInfo) { + public Collection find() { List mappings = myVcsManager.getDirectoryMappings(myVcs); - Collection gitRoots = rootDetectInfo.getRoots(); + Collection gitRoots = new GitRootDetector(myProject, myPlatformFacade).detect().getRoots(); Collection errors = new ArrayList(); Collection gitPaths = rootsToPaths(gitRoots); diff --git a/plugins/git4idea/src/git4idea/roots/GitRootProblemNotifier.java b/plugins/git4idea/src/git4idea/roots/GitRootProblemNotifier.java index 13665681761e..9f2d4bb17de3 100644 --- a/plugins/git4idea/src/git4idea/roots/GitRootProblemNotifier.java +++ b/plugins/git4idea/src/git4idea/roots/GitRootProblemNotifier.java @@ -67,19 +67,17 @@ public class GitRootProblemNotifier { mySettings = VcsConfiguration.getInstance(myProject); } - public GitRootDetectInfo rescanAndNotifyIfNeeded() { - GitRootDetectInfo detectInfo = new GitRootDetector(myProject, myPlatformFacade).detect(); - + public void rescanAndNotifyIfNeeded() { if (!mySettings.SHOW_VCS_ERROR_NOTIFICATIONS) { - return detectInfo; + return; } - Collection errors = scan(detectInfo); + Collection errors = scan(); if (errors.isEmpty()) { synchronized (NOTIFICATION_LOCK) { expireNotification(); } - return detectInfo; + return; } Collection unregisteredRoots = getUnregisteredRoots(errors); @@ -91,10 +89,9 @@ public class GitRootProblemNotifier { synchronized (NOTIFICATION_LOCK) { expireNotification(); myNotification = createNotification(IMPORTANT_ERROR_NOTIFICATION, title, description, ERROR, - new MyNotificationListener(myProject, mySettings, myPlatformFacade)); + new MyNotificationListener(myProject, mySettings)); myPlatformFacade.getNotificator(myProject).notify(myNotification); } - return detectInfo; } private void expireNotification() { @@ -112,8 +109,8 @@ public class GitRootProblemNotifier { } @NotNull - private Collection scan(GitRootDetectInfo detectInfo) { - return new GitRootErrorsFinder(myProject, myPlatformFacade).find(detectInfo); + private Collection scan() { + return new GitRootErrorsFinder(myProject, myPlatformFacade).find(); } @SuppressWarnings("StringConcatenationInsideStringBufferAppend") @@ -198,12 +195,10 @@ public class GitRootProblemNotifier { @NotNull private final Project myProject; @NotNull private final VcsConfiguration mySettings; - @NotNull private final PlatformFacade myPlatformFacade; - private MyNotificationListener(@NotNull Project project, @NotNull VcsConfiguration settings, @NotNull PlatformFacade facade) { + private MyNotificationListener(@NotNull Project project, @NotNull VcsConfiguration settings) { myProject = project; mySettings = settings; - myPlatformFacade = facade; } @Override @@ -211,8 +206,7 @@ public class GitRootProblemNotifier { if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { if (event.getDescription().equals("configure")) { ShowSettingsUtil.getInstance().showSettingsDialog(myProject, ActionsBundle.message("group.VcsGroup.text")); - Collection errorsAfterPossibleFix = GitRootProblemNotifier.getInstance(myProject).scan( - new GitRootDetector(myProject, myPlatformFacade).detect()); + Collection errorsAfterPossibleFix = GitRootProblemNotifier.getInstance(myProject).scan(); if (errorsAfterPossibleFix.isEmpty() && !notification.isExpired()) { notification.expire(); } diff --git a/plugins/git4idea/src/git4idea/roots/GitRootScanner.java b/plugins/git4idea/src/git4idea/roots/GitRootScanner.java index 28846df88e02..9c0c37bdffca 100644 --- a/plugins/git4idea/src/git4idea/roots/GitRootScanner.java +++ b/plugins/git4idea/src/git4idea/roots/GitRootScanner.java @@ -30,7 +30,6 @@ import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.newvfs.BulkFileListener; import com.intellij.openapi.vfs.newvfs.events.VFileEvent; import com.intellij.util.messages.MessageBus; -import git4idea.repo.GitRepositoryManager; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -41,7 +40,6 @@ import java.util.List; */ public class GitRootScanner implements BulkFileListener, ModuleRootListener, Disposable, VcsListener { - @NotNull private final Project myProject; @NotNull private final Runnable myExecuteAfterScan; @NotNull private final GitRootProblemNotifier myRootProblemNotifier; @@ -51,7 +49,6 @@ public class GitRootScanner implements BulkFileListener, ModuleRootListener, Dis @NotNull private final Object SCAN_LOCK = new Object(); public GitRootScanner(@NotNull Project project, @NotNull Runnable executeAfterScan) { - myProject = project; myExecuteAfterScan = executeAfterScan; StartupManager.getInstance(project).runWhenProjectIsInitialized(new DumbAwareRunnable() { @@ -132,8 +129,7 @@ public class GitRootScanner implements BulkFileListener, ModuleRootListener, Dis return; } myScanning = true; - GitRootDetectInfo detectInfo = myRootProblemNotifier.rescanAndNotifyIfNeeded(); - myProject.getMessageBus().syncPublisher(GitRepositoryManager.GIT_ROOTS_CHANGE).gitRootsChanged(detectInfo.getRoots()); + myRootProblemNotifier.rescanAndNotifyIfNeeded(); myExecuteAfterScan.run(); myScanning = false; } diff --git a/plugins/git4idea/src/git4idea/roots/GitRootsListener.java b/plugins/git4idea/src/git4idea/roots/GitRootsListener.java deleted file mode 100644 index 62c07c802fcf..000000000000 --- a/plugins/git4idea/src/git4idea/roots/GitRootsListener.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package git4idea.roots; - -import com.intellij.openapi.vfs.VirtualFile; - -import java.util.Collection; - -/** - * @author Kirill Likhodedov - */ -public interface GitRootsListener { - - void gitRootsChanged(Collection roots); - -} diff --git a/plugins/git4idea/tests/git4idea/roots/GitRootErrorsFinderTest.groovy b/plugins/git4idea/tests/git4idea/roots/GitRootErrorsFinderTest.groovy index 74bffd57c458..cf002e7a74b6 100644 --- a/plugins/git4idea/tests/git4idea/roots/GitRootErrorsFinderTest.groovy +++ b/plugins/git4idea/tests/git4idea/roots/GitRootErrorsFinderTest.groovy @@ -172,8 +172,7 @@ class GitRootErrorsFinderTest extends AbstractGitRootTest { expected.addAll map.errors.unreg.collect { unreg(it) } expected.addAll map.errors.extra.collect { extra(it) } - Collection actual = new GitRootErrorsFinder(myProject, myPlatformFacade).find( - new GitRootDetector(myProject, myPlatformFacade).detect()) + Collection actual = new GitRootErrorsFinder(myProject, myPlatformFacade).find() assertEquals expected.toSet(), actual.toSet() } From fa81befe2df3ba6aa228d3251658025f8209947c Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Thu, 15 Mar 2012 14:41:24 +0400 Subject: [PATCH 02/21] Revert "Detect nested roots in folders for mapping." Reason: detect nested folders can't be implemented easily - need change in ModuleDefaultVcsRootPolicy, not now. This reverts commit d3f23906a804af1800c0c0757995acc0709d395c. --- .../src/git4idea/GitRootConverter.java | 29 +------------- plugins/git4idea/src/git4idea/GitVcs.java | 4 +- .../git4idea/roots/GitRootErrorsFinder.java | 38 ++++--------------- .../roots/GitRootErrorsFinderTest.groovy | 9 +++-- .../git4idea/test/GitMockVcsManager.groovy | 1 - 5 files changed, 16 insertions(+), 65 deletions(-) diff --git a/plugins/git4idea/src/git4idea/GitRootConverter.java b/plugins/git4idea/src/git4idea/GitRootConverter.java index 1e29fde47f51..0250524bcaf5 100644 --- a/plugins/git4idea/src/git4idea/GitRootConverter.java +++ b/plugins/git4idea/src/git4idea/GitRootConverter.java @@ -16,13 +16,9 @@ package git4idea; -import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.AbstractVcs; -import com.intellij.openapi.vcs.VcsDirectoryMapping; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.HashSet; -import git4idea.roots.GitRootDetectInfo; -import git4idea.roots.GitRootDetector; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -33,23 +29,12 @@ import java.util.List; */ public class GitRootConverter implements AbstractVcs.RootsConvertor { - @NotNull private final Project myProject; - @NotNull private final PlatformFacade myPlatformFacade; - - public GitRootConverter(@NotNull Project project, @NotNull PlatformFacade facade) { - myProject = project; - myPlatformFacade = facade; - } + public static final GitRootConverter INSTANCE = new GitRootConverter(); @NotNull public List convertRoots(@NotNull List result) { - GitRootDetectInfo detectInfo = new GitRootDetector(myProject, myPlatformFacade).detect(); - + // TODO this should be faster, because it is called rather often. gitRootOrNull could be a bottle-neck. ArrayList roots = new ArrayList(); - if (hasProjectMapping()) { - roots.addAll(detectInfo.getRoots()); - } - HashSet listed = new HashSet(); for (VirtualFile f : result) { VirtualFile r = GitUtil.gitRootOrNull(f); @@ -59,14 +44,4 @@ public class GitRootConverter implements AbstractVcs.RootsConvertor { } return roots; } - - private boolean hasProjectMapping() { - for (VcsDirectoryMapping mapping : myPlatformFacade.getVcsManager(myProject).getDirectoryMappings()) { - if (mapping.isDefaultMapping()) { - return true; - } - } - return false; - } - } diff --git a/plugins/git4idea/src/git4idea/GitVcs.java b/plugins/git4idea/src/git4idea/GitVcs.java index 6f4e778b7655..8bee54c341f3 100644 --- a/plugins/git4idea/src/git4idea/GitVcs.java +++ b/plugins/git4idea/src/git4idea/GitVcs.java @@ -135,7 +135,6 @@ public class GitVcs extends AbstractVcs { private GitBranchWidget myBranchWidget; private GitVersion myVersion = GitVersion.NULL; // version of Git which this plugin uses. - private final GitRootConverter myRootConverter; @Nullable public static GitVcs getInstance(Project project) { @@ -175,7 +174,6 @@ public class GitVcs extends AbstractVcs { myTaskQueue = new BackgroundTaskQueue(myProject, GitBundle.getString("task.queue.title")); myExecutableValidator = new GitExecutableValidator(myProject, this); myPlatformFacade = ServiceManager.getService(myProject, PlatformFacade.class); - myRootConverter = new GitRootConverter(myProject, myPlatformFacade); } @@ -497,7 +495,7 @@ public class GitVcs extends AbstractVcs { @Override public RootsConvertor getCustomConvertor() { - return myRootConverter; + return GitRootConverter.INSTANCE; } public static VcsKey getKey() { diff --git a/plugins/git4idea/src/git4idea/roots/GitRootErrorsFinder.java b/plugins/git4idea/src/git4idea/roots/GitRootErrorsFinder.java index 8f68c17ef72f..8f03a93e0d0f 100644 --- a/plugins/git4idea/src/git4idea/roots/GitRootErrorsFinder.java +++ b/plugins/git4idea/src/git4idea/roots/GitRootErrorsFinder.java @@ -25,6 +25,7 @@ import git4idea.PlatformFacade; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -53,21 +54,17 @@ public class GitRootErrorsFinder { Collection gitRoots = new GitRootDetector(myProject, myPlatformFacade).detect().getRoots(); Collection errors = new ArrayList(); - Collection gitPaths = rootsToPaths(gitRoots); - errors.addAll(findExtraMappings(mappings, gitPaths)); - errors.addAll(findUnregisteredRoots(mappings, gitPaths)); + errors.addAll(findExtraMappings(mappings, rootsToPaths(gitRoots))); + errors.addAll(findUnregisteredRoots(gitRoots)); return errors; } - private Collection findUnregisteredRoots(List mappings, Collection gitPaths) { + private Collection findUnregisteredRoots(Collection gitRoots) { Collection errors = new ArrayList(); - if (hasProjectMapping(myPlatformFacade.getVcsManager(myProject).getDirectoryMappings())) { - return errors; - } - List mappedPaths = mappingsToPaths(mappings); - for (String gitPath : gitPaths) { - if (!mappedPaths.contains(gitPath)) { - errors.add(new VcsRootError(VcsRootError.Type.UNREGISTERED_ROOT, gitPath)); + Collection vcsRoots = Arrays.asList(myVcsManager.getRootsUnderVcs(myVcs)); + for (VirtualFile gitRoot : gitRoots) { + if (!vcsRoots.contains(gitRoot)) { + errors.add(new VcsRootError(VcsRootError.Type.UNREGISTERED_ROOT, gitRoot.getPath())); } } return errors; @@ -100,23 +97,4 @@ public class GitRootErrorsFinder { return gitPaths; } - private static List mappingsToPaths(List mappings) { - List paths = new ArrayList(); - for (VcsDirectoryMapping mapping : mappings) { - if (!mapping.isDefaultMapping()) { - paths.add(mapping.systemIndependentPath()); - } - } - return paths; - } - - private static boolean hasProjectMapping(List mappings) { - for (VcsDirectoryMapping mapping : mappings) { - if (mapping.isDefaultMapping()) { - return true; - } - } - return false; - } - } diff --git a/plugins/git4idea/tests/git4idea/roots/GitRootErrorsFinderTest.groovy b/plugins/git4idea/tests/git4idea/roots/GitRootErrorsFinderTest.groovy index cf002e7a74b6..f40b1a590cda 100644 --- a/plugins/git4idea/tests/git4idea/roots/GitRootErrorsFinderTest.groovy +++ b/plugins/git4idea/tests/git4idea/roots/GitRootErrorsFinderTest.groovy @@ -131,19 +131,20 @@ class GitRootErrorsFinderTest extends AbstractGitRootTest { } @Test - void "Project root, git below project folder not in a content root, then correct since folders are auto-detected"() { + void "Project root, git below project folder not in a content root, then unregistered root error"() { + // this is to be fixed: auto-detection of Git repositories in subfolders for the mapping doTest content_roots: ["."], git: ["community"], roots: [PROJECT], - errors: [] + errors: [unreg: ["community"]] } @Test - void "Project root, git for full project, content root, linked source, folder below project, then correct since folders are detected"() { + void "Project root, git for full project, content root, linked source, folder below project, then error in folder below"() { doTest content_roots: [".", "content_root", "../linked_source_root"], git: [".", "content_root", "../linked_source_root", "folder"], roots: [PROJECT], - errors: [] + errors: [unreg: ["folder"]] } @Test diff --git a/plugins/git4idea/tests/git4idea/test/GitMockVcsManager.groovy b/plugins/git4idea/tests/git4idea/test/GitMockVcsManager.groovy index 779ba4173494..4486690c47f2 100644 --- a/plugins/git4idea/tests/git4idea/test/GitMockVcsManager.groovy +++ b/plugins/git4idea/tests/git4idea/test/GitMockVcsManager.groovy @@ -57,7 +57,6 @@ public class GitMockVcsManager extends ProjectLevelVcsManager { List roots = myRoots.collect { new GitMockVirtualFile(it) } roots.addAll(myPlatformFacade.getProjectRootManager(myProject).getContentRoots()) roots -// new GitRootConverter(myProject, myPlatformFacade).convertRoots(roots) } @Override From 6db096f4784bafa6374ed8aaecf04397c4381955 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Thu, 15 Mar 2012 15:42:44 +0400 Subject: [PATCH 03/21] IDEA-82799 Don't show Git root error on successful Git integration enable Add .git dir to VFS after calling git init, so that GitRootDetector reacting on VCS mappings change would detect it. --- .../git4idea/src/git4idea/PlatformFacade.java | 2 ++ .../src/git4idea/PlatformFacadeImpl.java | 5 +++++ .../git4idea/roots/GitIntegrationEnabler.java | 17 ++++++++++++++++- .../git4idea/test/GitTestPlatformFacade.groovy | 5 +++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/plugins/git4idea/src/git4idea/PlatformFacade.java b/plugins/git4idea/src/git4idea/PlatformFacade.java index 8e8e60f55a58..4b7bd2146c9d 100644 --- a/plugins/git4idea/src/git4idea/PlatformFacade.java +++ b/plugins/git4idea/src/git4idea/PlatformFacade.java @@ -59,4 +59,6 @@ public interface PlatformFacade { * Invokes {@link com.intellij.openapi.application.Application#runReadAction(Computable)}. */ T runReadAction(@NotNull Computable computable); + + void runReadAction(@NotNull Runnable runnable); } diff --git a/plugins/git4idea/src/git4idea/PlatformFacadeImpl.java b/plugins/git4idea/src/git4idea/PlatformFacadeImpl.java index 0a7601305b18..1748811c1c90 100644 --- a/plugins/git4idea/src/git4idea/PlatformFacadeImpl.java +++ b/plugins/git4idea/src/git4idea/PlatformFacadeImpl.java @@ -57,6 +57,11 @@ public class PlatformFacadeImpl implements PlatformFacade { return ApplicationManager.getApplication().runReadAction(computable); } + @Override + public void runReadAction(@NotNull Runnable runnable) { + ApplicationManager.getApplication().runReadAction(runnable); + } + @NotNull @Override public AbstractVcs getVcs(@NotNull Project project) { diff --git a/plugins/git4idea/src/git4idea/roots/GitIntegrationEnabler.java b/plugins/git4idea/src/git4idea/roots/GitIntegrationEnabler.java index 0ac640759235..ae1765dc4aaa 100644 --- a/plugins/git4idea/src/git4idea/roots/GitIntegrationEnabler.java +++ b/plugins/git4idea/src/git4idea/roots/GitIntegrationEnabler.java @@ -21,7 +21,9 @@ import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.VcsDirectoryMapping; import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.ui.UIUtil; import git4idea.Notificator; import git4idea.PlatformFacade; import git4idea.commands.Git; @@ -74,9 +76,10 @@ public class GitIntegrationEnabler { notificator.notifySuccess("", String.format("Added Git %s: %s", pluralize("root", roots.size()), joinRootsPaths(roots))); } - private boolean gitInitOrNotifyError(@NotNull Notificator notificator, @NotNull VirtualFile projectDir) { + private boolean gitInitOrNotifyError(@NotNull Notificator notificator, @NotNull final VirtualFile projectDir) { try { myGit.init(myProject, projectDir); + refreshGitDir(projectDir); notificator.notifySuccess("", "Created Git repository in \n" + projectDir.getPresentableUrl()); return true; } @@ -87,6 +90,18 @@ public class GitIntegrationEnabler { } } + private void refreshGitDir(final VirtualFile projectDir) { + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override public void run() { + myPlatformFacade.runReadAction(new Runnable() { + @Override public void run() { + LocalFileSystem.getInstance().refreshAndFindFileByPath(projectDir.getPath() + "/.git"); + } + }); + } + }); + } + private void addVcsRoots(@NotNull Collection roots) { ProjectLevelVcsManager vcsManager = myPlatformFacade.getVcsManager(myProject); AbstractVcs vcs = myPlatformFacade.getVcs(myProject); diff --git a/plugins/git4idea/tests/git4idea/test/GitTestPlatformFacade.groovy b/plugins/git4idea/tests/git4idea/test/GitTestPlatformFacade.groovy index 5559051898ab..ca0467020269 100644 --- a/plugins/git4idea/tests/git4idea/test/GitTestPlatformFacade.groovy +++ b/plugins/git4idea/tests/git4idea/test/GitTestPlatformFacade.groovy @@ -77,6 +77,11 @@ public class GitTestPlatformFacade implements PlatformFacade { computable.compute() } + @Override + void runReadAction(Runnable runnable) { + runnable.run() + } + @NotNull @Override AbstractVcs getVcs(@NotNull Project project) { From 77b8bfdf40f503a226ec06346af5e5a083b28a9d Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Thu, 15 Mar 2012 13:29:25 +0400 Subject: [PATCH 04/21] IDEA-76142: Gradle support - cannot update IDEA projects once one of build.gradle files changes Logging java version used by the gradle api --- .../plugins/gradle/remote/GradleApiFacadeManager.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java index 3f884ccec8b2..9994b4c74bdf 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java @@ -236,7 +236,10 @@ public class GradleApiFacadeManager { GradleLog.LOG.warn("Detected unexpected duplicate tooling api facade instance creation"); return myFacade.get().first; } - result.applySettings(getRemoteSettings()); + if (!StringUtil.isEmpty(newPair.second.getJavaHome())) { + GradleLog.LOG.info("Instructing gradle to use java from " + newPair.second.getJavaHome()); + } + result.applySettings(newPair.second); RemoteGradleProgressNotificationManager exported = myExportedProgressManager.get(); if (exported == null) { try { From ece9df8cb0d400094fc47241324e205e1b342323 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Thu, 15 Mar 2012 15:48:07 +0400 Subject: [PATCH 05/21] IDEA-76142: Gradle support - cannot update IDEA projects once one of build.gradle files changes Added ability to launch gradle api at the 'verbose' mode (activated by the 'gradle.api.verbose' system property --- .../remote/RemoteGradleProcessSettings.java | 18 +++++++++++++++--- .../remote/impl/GradleProjectResolverImpl.java | 4 ++++ .../GradleProjectStructureChangesPanel.java | 2 +- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/RemoteGradleProcessSettings.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/RemoteGradleProcessSettings.java index 826988950428..3f67572335f3 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/RemoteGradleProcessSettings.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/RemoteGradleProcessSettings.java @@ -16,14 +16,18 @@ import java.io.Serializable; */ public class RemoteGradleProcessSettings implements Serializable { + private static final boolean USE_VERBOSE_GRADLE_API_BY_DEFAULT = Boolean.parseBoolean(System.getProperty("gradle.api.verbose")); + private static final long serialVersionUID = 1L; - private final String myGradleHome; - private long myTtlInMs; - private String myJavaHome; + private final String myGradleHome; + private long myTtlInMs; + private String myJavaHome; + private boolean myVerboseApi; public RemoteGradleProcessSettings(@NotNull String gradleHome) { myGradleHome = gradleHome; + setVerboseApi(USE_VERBOSE_GRADLE_API_BY_DEFAULT); } @NotNull @@ -51,6 +55,14 @@ public class RemoteGradleProcessSettings implements Serializable { myJavaHome = javaHome; } + public boolean isVerboseApi() { + return myVerboseApi; + } + + public void setVerboseApi(boolean verboseApi) { + myVerboseApi = verboseApi; + } + @Override public String toString() { return "home: " + myGradleHome; diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleProjectResolverImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleProjectResolverImpl.java index 8764ece4961f..898d65f2bb24 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleProjectResolverImpl.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/impl/GradleProjectResolverImpl.java @@ -8,6 +8,7 @@ import com.intellij.util.PathUtil; import com.intellij.util.containers.ConcurrentHashSet; import com.intellij.util.containers.HashMap; import org.gradle.tooling.*; +import org.gradle.tooling.internal.consumer.DefaultGradleConnector; import org.gradle.tooling.model.DomainObjectSet; import org.gradle.tooling.model.idea.*; import org.jetbrains.annotations.NotNull; @@ -398,6 +399,9 @@ public class GradleProjectResolverImpl extends RemoteObject implements GradlePro RemoteGradleProcessSettings settings = mySettings.get(); if (settings != null) { connector.useInstallation(new File(settings.getGradleHome())); + if (settings.isVerboseApi() && connector instanceof DefaultGradleConnector) { + ((DefaultGradleConnector)connector).setVerboseLogging(true); + } } connector.forProjectDirectory(projectDir); ProjectConnection connection = connector.connect(); diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java index 239e313cefd5..9837b71caf9d 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java @@ -59,7 +59,7 @@ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel { private final Alarm myToolbarAppearanceAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); private final Alarm myToolbarTrackingAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); - private final Alarm myCollapseStateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); + private final Alarm myCollapseStateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); private final List myToolbarControls = new ArrayList(); /** Holds list of paths which 'expand/collapse' state should be restored. */ From f406a46b17d0cced559b737790190aea010b2dd8 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 15 Mar 2012 12:08:38 +0100 Subject: [PATCH 06/21] inspections: align icons --- .../ui/SingleInspectionProfilePanel.java | 114 ++++++++++-------- 1 file changed, 61 insertions(+), 53 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java index 911243734158..f1ce219c845e 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java @@ -568,7 +568,7 @@ public class SingleInspectionProfilePanel extends JPanel { } private JPopupMenu compoundPopup() { - final JPopupMenu popup = new JPopupMenu(InspectionsBundle.message("inspection.error.level.popup.menu.title")); + final DefaultActionGroup group = new DefaultActionGroup(); final SeverityRegistrar severityRegistrar = ((SeverityProvider)mySelectedProfile.getProfileManager()).getOwnSeverityRegistrar(); TreeSet severities = new TreeSet(severityRegistrar); severities.add(HighlightSeverity.ERROR); @@ -581,12 +581,15 @@ public class SingleInspectionProfilePanel extends JPanel { } for (HighlightSeverity severity : severities) { final HighlightDisplayLevel level = HighlightDisplayLevel.find(severity); - final JMenuItem item = new JMenuItem(renderSeverity(level.getSeverity())); - item.setIcon(level.getIcon()); //todo correct position - item.addActionListener(new LevelSelection(level)); - popup.add(item); + group.add(new AnAction(renderSeverity(severity), renderSeverity(severity), level.getIcon()) { + @Override + public void actionPerformed(AnActionEvent e) { + setNewHighlightingLevel(level); + } + }); } - return popup; + ActionPopupMenu menu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.UNKNOWN, group); + return menu.getComponent(); } static String renderSeverity(HighlightSeverity severity) { @@ -1051,6 +1054,57 @@ public class SingleInspectionProfilePanel extends JPanel { super.setVisible(aFlag); } + private void setNewHighlightingLevel(final HighlightDisplayLevel level) { + final int[] rows = myTree.getSelectionRows(); + final boolean showOptionsAndDescriptorPanels = rows != null && rows.length == 1; + for (int i = 0; rows != null && i < rows.length; i++) { + final InspectionConfigTreeNode node = (InspectionConfigTreeNode)myTree.getPathForRow(rows[i]).getLastPathComponent(); + final InspectionConfigTreeNode parent = (InspectionConfigTreeNode)node.getParent(); + if (node.getUserObject() instanceof Descriptor) { + updateErrorLevel(node, showOptionsAndDescriptorPanels, level); + updateUpHierarchy(node, parent); + } + else { + node.isProperSetting = false; + for (int j = 0; j < node.getChildCount(); j++) { + final InspectionConfigTreeNode child = (InspectionConfigTreeNode)node.getChildAt(j); + if (child.getUserObject() instanceof Descriptor) { //group node + updateErrorLevel(child, showOptionsAndDescriptorPanels, level); + } + else { //root node + child.isProperSetting = false; + for (int k = 0; k < child.getChildCount(); k++) { + final InspectionConfigTreeNode descriptorNode = (InspectionConfigTreeNode)child.getChildAt(k); + if (descriptorNode.getUserObject() instanceof Descriptor) { + updateErrorLevel(descriptorNode, showOptionsAndDescriptorPanels, level); + } + child.isProperSetting |= descriptorNode.isProperSetting; + } + } + node.isProperSetting |= child.isProperSetting; + } + updateUpHierarchy(node, parent); + } + } + if (rows != null && rows.length == 1) { + updateOptionsAndDescriptionPanel(myTree.getPathForRow(rows[0])); + } + else { + initOptionsAndDescriptionPanel(); + } + repaintTableData(); + } + + private void updateErrorLevel(final InspectionConfigTreeNode child, + final boolean showOptionsAndDescriptorPanels, final HighlightDisplayLevel level) { + final HighlightDisplayKey key = child.getDesriptor().getKey(); + mySelectedProfile.setErrorLevel(key, level, child.isInspectionNode() || child.isByDefault() ? -1 : child.getParent().getIndex(child)); + child.isProperSetting = mySelectedProfile.isProperSetting(key); + if (showOptionsAndDescriptorPanels) { + updateOptionsAndDescriptionPanel(new TreePath(child.getPath())); + } + } + private class LevelSelection implements ActionListener { private final HighlightDisplayLevel myLevel; @@ -1059,53 +1113,7 @@ public class SingleInspectionProfilePanel extends JPanel { } public void actionPerformed(ActionEvent e) { - final int[] rows = myTree.getSelectionRows(); - final boolean showOptionsAndDescriptorPanels = rows != null && rows.length == 1; - for (int i = 0; rows != null && i < rows.length; i++) { - final InspectionConfigTreeNode node = (InspectionConfigTreeNode)myTree.getPathForRow(rows[i]).getLastPathComponent(); - final InspectionConfigTreeNode parent = (InspectionConfigTreeNode)node.getParent(); - if (node.getUserObject() instanceof Descriptor) { - updateErrorLevel(node, showOptionsAndDescriptorPanels); - updateUpHierarchy(node, parent); - } - else { - node.isProperSetting = false; - for (int j = 0; j < node.getChildCount(); j++) { - final InspectionConfigTreeNode child = (InspectionConfigTreeNode)node.getChildAt(j); - if (child.getUserObject()instanceof Descriptor) { //group node - updateErrorLevel(child, showOptionsAndDescriptorPanels); - } - else { //root node - child.isProperSetting = false; - for (int k = 0; k < child.getChildCount(); k++) { - final InspectionConfigTreeNode descriptorNode = (InspectionConfigTreeNode)child.getChildAt(k); - if (descriptorNode.getUserObject()instanceof Descriptor) { - updateErrorLevel(descriptorNode, showOptionsAndDescriptorPanels); - } - child.isProperSetting |= descriptorNode.isProperSetting; - } - } - node.isProperSetting |= child.isProperSetting; - } - updateUpHierarchy(node, parent); - } - } - if (rows != null && rows.length == 1) { - updateOptionsAndDescriptionPanel(myTree.getPathForRow(rows[0])); - } - else { - initOptionsAndDescriptionPanel(); - } - repaintTableData(); - } - - private void updateErrorLevel(final InspectionConfigTreeNode child, final boolean showOptionsAndDescriptorPanels) { - final HighlightDisplayKey key = child.getDesriptor().getKey(); - mySelectedProfile.setErrorLevel(key, myLevel, child.isInspectionNode() || child.isByDefault() ? -1 : child.getParent().getIndex(child)); - child.isProperSetting = mySelectedProfile.isProperSetting(key); - if (showOptionsAndDescriptorPanels) { - updateOptionsAndDescriptionPanel(new TreePath(child.getPath())); - } + setNewHighlightingLevel(myLevel); } } From 54ada9f751a51dd4c9516422c19a5c3aef9c48c7 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 15 Mar 2012 12:46:53 +0100 Subject: [PATCH 07/21] correctly find change list by name --- .../intellij/packageDependencies/ChangeListsScopesProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/ChangeListsScopesProvider.java b/platform/lang-impl/src/com/intellij/packageDependencies/ChangeListsScopesProvider.java index 7229c7dd08dc..1e9dcaeddd26 100644 --- a/platform/lang-impl/src/com/intellij/packageDependencies/ChangeListsScopesProvider.java +++ b/platform/lang-impl/src/com/intellij/packageDependencies/ChangeListsScopesProvider.java @@ -79,7 +79,7 @@ public class ChangeListsScopesProvider extends CustomScopesProviderEx { if (IdeBundle.message("scope.modified.files").equals(name)) { return createScope(changeListManager.getAffectedFiles(), IdeBundle.message("scope.modified.files")); } - final LocalChangeList changeList = changeListManager.getChangeList(name); + final LocalChangeList changeList = changeListManager.findChangeList(name); if (changeList != null) { return createChangeListScope(changeList); } From cf157dbda46c3ff0e7e42ad96e8b707c86ec43c2 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 15 Mar 2012 12:49:59 +0100 Subject: [PATCH 08/21] inspections: allow to add multiple scopes over selection from popup --- .../ui/SingleInspectionProfilePanel.java | 51 ++++++++++----- .../ui/actions/AddScopeAction.java | 65 +++++++++++-------- 2 files changed, 74 insertions(+), 42 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java index f1ce219c845e..dd3ebd75c5a5 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java @@ -379,22 +379,8 @@ public class SingleInspectionProfilePanel extends JPanel { }); actions.addSeparator(); - actions.add(new AddScopeAction(myTree){ - protected InspectionProfileImpl getSelectedProfile() { - return mySelectedProfile; - } - - @Override - public void actionPerformed(AnActionEvent e) { - super.actionPerformed(e); - updateOptionsAndDescriptionPanel(myTree.getSelectionPath()); - } - }); - actions.add(new DeleteScopeAction(myTree){ - protected InspectionProfileImpl getSelectedProfile() { - return mySelectedProfile; - } - }); + actions.add(new MyAddScopeAction()); + actions.add(new MyDeleteScopeAction()); actions.add(new MoveScopeAction(myTree, "Move Scope Up", IconLoader.getIcon("/actions/moveUp.png"), -1) { protected boolean isEnabledFor(int idx, InspectionConfigTreeNode parent) { return idx > 0; @@ -588,6 +574,9 @@ public class SingleInspectionProfilePanel extends JPanel { } }); } + group.add(Separator.getInstance()); + group.add(new MyAddScopeAction()); + group.add(new MyDeleteScopeAction()); ActionPopupMenu menu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.UNKNOWN, group); return menu.getComponent(); } @@ -1143,4 +1132,34 @@ public class SingleInspectionProfilePanel extends JPanel { } } + private class MyAddScopeAction extends AddScopeAction { + public MyAddScopeAction() { + super(SingleInspectionProfilePanel.this.myTree); + } + + protected InspectionProfileImpl getSelectedProfile() { + return mySelectedProfile; + } + + @Override + public void actionPerformed(AnActionEvent e) { + super.actionPerformed(e); + final TreePath[] paths = myTree.getSelectionPaths(); + if (paths != null && paths.length == 1) { + updateOptionsAndDescriptionPanel(myTree.getSelectionPath()); + } else { + initOptionsAndDescriptionPanel(); + } + } + } + + private class MyDeleteScopeAction extends DeleteScopeAction { + public MyDeleteScopeAction() { + super(SingleInspectionProfilePanel.this.myTree); + } + + protected InspectionProfileImpl getSelectedProfile() { + return mySelectedProfile; + } + } } diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/actions/AddScopeAction.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/actions/AddScopeAction.java index b6b321646101..15d705ccbc82 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/actions/AddScopeAction.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/actions/AddScopeAction.java @@ -59,54 +59,67 @@ public abstract class AddScopeAction extends AnAction { final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); if (project == null) return; final InspectionConfigTreeNode[] nodes = myTree.getSelectedNodes(InspectionConfigTreeNode.class, null); - if (nodes.length > 0) { - final InspectionConfigTreeNode node = nodes[0]; + final List descriptors = new ArrayList(); + for (InspectionConfigTreeNode node : nodes) { final Descriptor descriptor = node.getDesriptor(); - if (descriptor != null && node.getScopeName() == null && !getAvailableScopes(descriptor, project).isEmpty()) { - presentation.setEnabled(true); + if (descriptor != null && node.getScopeName() == null) { + descriptors.add(descriptor); } } + + presentation.setEnabled(!getAvailableScopes(project, descriptors).isEmpty()); } @Override public void actionPerformed(AnActionEvent e) { final InspectionConfigTreeNode[] nodes = myTree.getSelectedNodes(InspectionConfigTreeNode.class, null); - final InspectionConfigTreeNode node = nodes[0]; - final Descriptor descriptor = node.getDesriptor(); - LOG.assertTrue(descriptor != null); - final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); - final InspectionProfileEntry tool = descriptor.getTool(); //copy - final List availableScopes = getAvailableScopes(descriptor, project); + List descriptors = new ArrayList(); + for (InspectionConfigTreeNode node : nodes) { + final Descriptor descriptor = node.getDesriptor(); + if (node.getScopeName() == null && descriptor != null) { + descriptors.add(descriptor); + } + } + final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + final List availableScopes = getAvailableScopes(project, descriptors); final int idx = Messages.showChooseDialog(myTree, "Scope:", "Choose Scope", ArrayUtil.toStringArray(availableScopes), availableScopes.get(0), Messages.getQuestionIcon()); if (idx == -1) return; final NamedScope chosenScope = NamedScopesHolder.getScope(project, availableScopes.get(idx)); - final ScopeToolState scopeToolState = getSelectedProfile().addScope(tool, chosenScope, - getSelectedProfile().getErrorLevel(descriptor.getKey(), chosenScope), - getSelectedProfile().isToolEnabled(descriptor.getKey())); - final Descriptor addedDescriptor = new Descriptor(scopeToolState, getSelectedProfile()); - if (node.getChildCount() == 0) { - node.add(new InspectionConfigTreeNode(descriptor, scopeToolState, true, true, false)); + + for (InspectionConfigTreeNode node : nodes) { + final Descriptor descriptor = node.getDesriptor(); + if (node.getScopeName() != null || descriptor == null) continue; + final InspectionProfileEntry tool = descriptor.getTool(); //copy + final ScopeToolState scopeToolState = getSelectedProfile().addScope(tool, chosenScope, + getSelectedProfile().getErrorLevel(descriptor.getKey(), chosenScope), + getSelectedProfile().isToolEnabled(descriptor.getKey())); + final Descriptor addedDescriptor = new Descriptor(scopeToolState, getSelectedProfile()); + if (node.getChildCount() == 0) { + node.add(new InspectionConfigTreeNode(descriptor, scopeToolState, true, true, false)); + } + node.insert(new InspectionConfigTreeNode(addedDescriptor, scopeToolState, false, true, false), 0); + node.setInspectionNode(false); + node.isProperSetting = getSelectedProfile().isProperSetting(HighlightDisplayKey.find(tool.getShortName())); + ((DefaultTreeModel)myTree.getModel()).reload(node); + myTree.expandPath(new TreePath(node.getPath())); } - node.insert(new InspectionConfigTreeNode(addedDescriptor, scopeToolState, false, true, false), 0); - node.setInspectionNode(false); - node.isProperSetting = getSelectedProfile().isProperSetting(HighlightDisplayKey.find(tool.getShortName())); - ((DefaultTreeModel)myTree.getModel()).reload(node); - myTree.expandPath(new TreePath(node.getPath())); myTree.revalidate(); } - private List getAvailableScopes(Descriptor descriptor, Project project) { + private List getAvailableScopes(Project project, List descriptors) { final ArrayList scopes = new ArrayList(); for (NamedScopesHolder holder : NamedScopesHolder.getAllNamedScopeHolders(project)) { Collections.addAll(scopes, holder.getScopes()); } scopes.remove(DefaultScopesProvider.getAllScope()); final Set used = new HashSet(); - final List nonDefaultTools = getSelectedProfile().getNonDefaultTools(descriptor.getKey().toString()); - if (nonDefaultTools != null) { - for (ScopeToolState state : nonDefaultTools) { - used.add(state.getScope(project)); + for (Descriptor descriptor : descriptors) { + final List nonDefaultTools = getSelectedProfile().getNonDefaultTools(descriptor.getKey().toString()); + if (nonDefaultTools != null) { + for (ScopeToolState state : nonDefaultTools) { + used.add(state.getScope(project)); + } } } scopes.removeAll(used); From 578b81122f7394973d32123125b2f28dbdfc9dbc Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Thu, 15 Mar 2012 15:54:48 +0400 Subject: [PATCH 09/21] IDEA-76142: Gradle support - cannot update IDEA projects once one of build.gradle files changes 1. Don't show node toolbar if more than one node is selected; 2. Toolbar delay time is reduced; --- .../gradle/sync/GradleProjectStructureChangesPanel.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java index 9837b71caf9d..2e76f9341b26 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java @@ -47,7 +47,7 @@ import java.util.List; */ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel { - private static final int TOOLTIP_DELAY_MILLIS = 500; + private static final int TOOLTIP_DELAY_MILLIS = 300; private static final int COLLAPSE_STATE_PROCESSING_DELAY_MILLIS = 200; private static final Comparator PATH_COMPARATOR = new Comparator() { @@ -213,14 +213,14 @@ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel { final @NotNull ActionToolbar toolbar, final @NotNull JComponent toolbarComponent) { - if (mySuppressToolbar || node == myNodeWithActiveToolbar) { + if (mySuppressToolbar || node == myNodeWithActiveToolbar || myTree.getSelectionCount() > 1) { return; } myToolbarAppearanceAlarm.cancelAllRequests(); myToolbarAppearanceAlarm.addRequest(new Runnable() { @Override public void run() { - if (myNodeUnderMouse != node) { + if (myNodeUnderMouse != node || myTree.getSelectionCount() > 1) { return; } final Point mouseLocation = MouseInfo.getPointerInfo().getLocation(); From a6fe764c1671a1edf7bb60d985daf49e17680cb8 Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 15 Mar 2012 15:59:52 +0400 Subject: [PATCH 10/21] allow to specify command line options for Chrome (IDEA-77398) --- .../ide/browsers/chrome/ChromeSettings.java | 13 +++++++++- .../chrome/ChromeSettingsConfigurable.form | 26 ++++++++++++++----- .../chrome/ChromeSettingsConfigurable.java | 9 ++++++- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/xml/impl/src/com/intellij/ide/browsers/chrome/ChromeSettings.java b/xml/impl/src/com/intellij/ide/browsers/chrome/ChromeSettings.java index 9e470ac2022c..8f7b70d539ca 100644 --- a/xml/impl/src/com/intellij/ide/browsers/chrome/ChromeSettings.java +++ b/xml/impl/src/com/intellij/ide/browsers/chrome/ChromeSettings.java @@ -15,6 +15,7 @@ */ package com.intellij.ide.browsers.chrome; +import com.intellij.execution.configurations.ParametersList; import com.intellij.ide.browsers.BrowserSpecificSettings; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.ArrayUtil; @@ -30,6 +31,7 @@ public class ChromeSettings extends BrowserSpecificSettings { @NonNls public static final String REMOTE_DEBUGGING_PORT_ARG = "--remote-debugging-port="; @NonNls public static final String USER_DATA_DIR_ARG = "--user-data-dir="; public static final int DEFAULT_REMOTE_SHELL_PORT = 7930; + private String myCommandLineOptions = ""; private String myUserDataDirectoryPath; private boolean myUseCustomProfile; private boolean myEnableRemoteDebug; @@ -59,6 +61,15 @@ public class ChromeSettings extends BrowserSpecificSettings { return myRemoteShellPort; } + @Tag("command-line-options") + public String getCommandLineOptions() { + return myCommandLineOptions; + } + + public void setCommandLineOptions(String commandLineOptions) { + myCommandLineOptions = commandLineOptions; + } + public void setEnableRemoteDebug(boolean enableRemoteDebug) { myEnableRemoteDebug = enableRemoteDebug; } @@ -94,7 +105,7 @@ public class ChromeSettings extends BrowserSpecificSettings { remoteShellArg = ArrayUtil.EMPTY_STRING_ARRAY; } - return ArrayUtil.mergeArrays(customProfileArg, remoteShellArg); + return ArrayUtil.mergeArrays(ParametersList.parse(myCommandLineOptions), ArrayUtil.mergeArrays(customProfileArg, remoteShellArg)); } @Override diff --git a/xml/impl/src/com/intellij/ide/browsers/chrome/ChromeSettingsConfigurable.form b/xml/impl/src/com/intellij/ide/browsers/chrome/ChromeSettingsConfigurable.form index 39b81024be5c..f3013409e001 100644 --- a/xml/impl/src/com/intellij/ide/browsers/chrome/ChromeSettingsConfigurable.form +++ b/xml/impl/src/com/intellij/ide/browsers/chrome/ChromeSettingsConfigurable.form @@ -1,6 +1,6 @@
- + @@ -10,7 +10,7 @@ - + @@ -18,12 +18,12 @@ - + - + @@ -31,7 +31,7 @@ - + @@ -39,12 +39,26 @@ - + + + + + + + + + + + + + + + diff --git a/xml/impl/src/com/intellij/ide/browsers/chrome/ChromeSettingsConfigurable.java b/xml/impl/src/com/intellij/ide/browsers/chrome/ChromeSettingsConfigurable.java index 59ed138ddf1d..42ceaeb47caf 100644 --- a/xml/impl/src/com/intellij/ide/browsers/chrome/ChromeSettingsConfigurable.java +++ b/xml/impl/src/com/intellij/ide/browsers/chrome/ChromeSettingsConfigurable.java @@ -21,6 +21,7 @@ import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.ui.RawCommandLineEditor; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; @@ -40,6 +41,8 @@ public class ChromeSettingsConfigurable implements Configurable { private TextFieldWithBrowseButton myUserDataDirField; private JCheckBox myEnableRemoteDebugCheckBox; private JTextField myPortField; + private JLabel myCommandLineOptionsLabel; + private RawCommandLineEditor myCommandLineOptionsEditor; private final String myDefaultUserDirPath; public ChromeSettingsConfigurable(@NotNull ChromeSettings settings) { @@ -59,6 +62,7 @@ public class ChromeSettingsConfigurable implements Configurable { myPortField.setEnabled(myEnableRemoteDebugCheckBox.isSelected()); } }); + myCommandLineOptionsLabel.setLabelFor(myCommandLineOptionsEditor.getTextField()); } @Override @@ -70,7 +74,8 @@ public class ChromeSettingsConfigurable implements Configurable { public boolean isModified() { if (myEnableRemoteDebugCheckBox.isSelected() != mySettings.isEnableRemoteDebug() || !myPortField.getText().equals(String.valueOf(mySettings.getRemoteShellPort())) - || myUseCustomProfileCheckBox.isSelected() != mySettings.isUseCustomProfile()) { + || myUseCustomProfileCheckBox.isSelected() != mySettings.isUseCustomProfile() + || !myCommandLineOptionsEditor.getText().equals(mySettings.getCommandLineOptions())) { return true; } @@ -93,6 +98,7 @@ public class ChromeSettingsConfigurable implements Configurable { catch (NumberFormatException ignored) { throw new ConfigurationException("Port is not integer!"); } + mySettings.setCommandLineOptions(myCommandLineOptionsEditor.getText()); mySettings.setUseCustomProfile(myUseCustomProfileCheckBox.isSelected()); mySettings.setUserDataDirectoryPath(getConfiguredUserDataDirPath()); mySettings.setEnableRemoteDebug(myEnableRemoteDebugCheckBox.isSelected()); @@ -104,6 +110,7 @@ public class ChromeSettingsConfigurable implements Configurable { myPortField.setText(String.valueOf(mySettings.getRemoteShellPort())); myPortField.setEnabled(mySettings.isEnableRemoteDebug()); + myCommandLineOptionsEditor.setText(mySettings.getCommandLineOptions()); myUseCustomProfileCheckBox.setSelected(mySettings.isUseCustomProfile()); myUserDataDirField.setEnabled(mySettings.isUseCustomProfile()); String path = mySettings.getUserDataDirectoryPath(); From ea19cb45e5808149215c4069eb9e07ef8daac761 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Thu, 15 Mar 2012 16:07:51 +0400 Subject: [PATCH 11/21] IDEA-82807 Map help button and F1 for JetGradle tool window --- plugins/gradle/src/META-INF/plugin.xml | 1 + .../gradle/sync/GradleProjectStructureChangesPanel.java | 3 +++ .../src/org/jetbrains/plugins/gradle/util/GradleConstants.java | 1 + 3 files changed, 5 insertions(+) diff --git a/plugins/gradle/src/META-INF/plugin.xml b/plugins/gradle/src/META-INF/plugin.xml index a6919bcbbf21..b6a5ec5aa1e0 100644 --- a/plugins/gradle/src/META-INF/plugin.xml +++ b/plugins/gradle/src/META-INF/plugin.xml @@ -108,6 +108,7 @@ + diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java index 2e76f9341b26..fbb2edcd5409 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java @@ -319,6 +319,9 @@ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel { } return result; } + else if (PlatformDataKeys.HELP_ID.is(dataId)) { + return GradleConstants.HELP_TOPIC_TOOL_WINDOW; + } else { return super.getData(dataId); } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java index d43481149b38..ce2bcdc2c158 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java @@ -24,6 +24,7 @@ public class GradleConstants { @NonNls public static final String ACTION_GROUP_SYNC_TREE = "Gradle.SyncTreeGroup"; + @NonNls public static final String HELP_TOPIC_TOOL_WINDOW = "reference.toolwindows.gradle"; public static final GradleProjectStructureNodeDescriptor DEPENDENCIES_NODE_DESCRIPTOR = GradleUtil.buildSyntheticDescriptor(GradleBundle.message("gradle.project.structure.tree.node.dependencies")); From e88079252110402404ada906f4bbe7bcf2946afa Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Thu, 15 Mar 2012 16:19:20 +0400 Subject: [PATCH 12/21] IDEA-82810 Map help button for the page 2 of Import from Gradle (new project wizard) --- .../wizard/adjust/GradleAdjustImportSettingsStep.java | 6 +++++- .../importing/wizard/select/GradleSelectProjectStep.java | 6 ++++++ .../org/jetbrains/plugins/gradle/util/GradleConstants.java | 6 ++++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/adjust/GradleAdjustImportSettingsStep.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/adjust/GradleAdjustImportSettingsStep.java index 81e35d435fd7..51e53af5c892 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/adjust/GradleAdjustImportSettingsStep.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/adjust/GradleAdjustImportSettingsStep.java @@ -152,7 +152,11 @@ public class GradleAdjustImportSettingsStep extends AbstractImportFromGradleWiza public JComponent getComponent() { return myComponent; } - + @Override + public String getHelpId() { + return GradleConstants.HELP_TOPIC_ADJUST_SETTINGS_STEP; + } + @Override public void updateStep() { if (myOnValidateAttempt) { diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/select/GradleSelectProjectStep.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/select/GradleSelectProjectStep.java index 36d1d71fd131..32f381b37993 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/select/GradleSelectProjectStep.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/wizard/select/GradleSelectProjectStep.java @@ -13,6 +13,7 @@ import org.jetbrains.plugins.gradle.config.GradleHomeSettingType; import org.jetbrains.plugins.gradle.importing.GradleProjectImportBuilder; import org.jetbrains.plugins.gradle.importing.wizard.AbstractImportFromGradleWizardStep; import org.jetbrains.plugins.gradle.util.GradleBundle; +import org.jetbrains.plugins.gradle.util.GradleConstants; import org.jetbrains.plugins.gradle.util.GradleUtil; import javax.swing.*; @@ -86,6 +87,11 @@ public class GradleSelectProjectStep extends AbstractImportFromGradleWizardStep public void updateDataModel() { } + @Override + public String getHelpId() { + return GradleConstants.HELP_TOPIC_IMPORT_SELECT_PROJECT_STEP; + } + @Override public boolean validate() throws ConfigurationException { if (myConfigurable.getCurrentGradleHomeSettingType() == GradleHomeSettingType.EXPLICIT_INCORRECT) { diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java index ce2bcdc2c158..4e7f2d577923 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java @@ -23,8 +23,10 @@ public class GradleConstants { @NonNls public static final String SYNC_TREE_FILTER_PLACE = "GRADLE_SYNC_TREE_FILTER_PLACE"; @NonNls public static final String ACTION_GROUP_SYNC_TREE = "Gradle.SyncTreeGroup"; - - @NonNls public static final String HELP_TOPIC_TOOL_WINDOW = "reference.toolwindows.gradle"; + + @NonNls public static final String HELP_TOPIC_IMPORT_SELECT_PROJECT_STEP = "reference.dialogs.new.project.import.gradle.page1"; + @NonNls public static final String HELP_TOPIC_ADJUST_SETTINGS_STEP = "reference.dialogs.new.project.import.gradle.page2"; + @NonNls public static final String HELP_TOPIC_TOOL_WINDOW = "reference.toolwindows.gradle"; public static final GradleProjectStructureNodeDescriptor DEPENDENCIES_NODE_DESCRIPTOR = GradleUtil.buildSyntheticDescriptor(GradleBundle.message("gradle.project.structure.tree.node.dependencies")); From 6b7184e162e90628e1bfd95d5a738a76c3ba6437 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Thu, 15 Mar 2012 16:20:14 +0400 Subject: [PATCH 13/21] IDEA-82801 Gradle: New Project Wizard: change "Sdk" to "SDK" --- plugins/gradle/resources/i18n/GradleBundle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/gradle/resources/i18n/GradleBundle.properties b/plugins/gradle/resources/i18n/GradleBundle.properties index 4993111dcfad..cec812d7e1d1 100644 --- a/plugins/gradle/resources/i18n/GradleBundle.properties +++ b/plugins/gradle/resources/i18n/GradleBundle.properties @@ -14,7 +14,7 @@ gradle.import.structure.tree.node.content.root=content-root gradle.import.structure.tree.node.libraries=libraries gradle.import.structure.settings.label.name=Name: gradle.import.structure.settings.label.language.level=Language level: -gradle.import.structure.settings.label.sdk=Sdk: +gradle.import.structure.settings.label.sdk=SDK: gradle.import.structure.settings.no.sdk.for.language.level.text= gradle.import.structure.settings.label.project.config.location=Project config location: gradle.import.structure.settings.title.project.config.location=Project config location From 6aa6816b82f87cac7de971028425462e25ee0f0d Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Wed, 14 Mar 2012 13:15:23 +0100 Subject: [PATCH 14/21] AppCode:Plists: writing xml plist with JDOM, support for Number values (OC-3293, OC-3291) --- .../com/intellij/util/NotNullProducer.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 platform/util/src/com/intellij/util/NotNullProducer.java diff --git a/platform/util/src/com/intellij/util/NotNullProducer.java b/platform/util/src/com/intellij/util/NotNullProducer.java new file mode 100644 index 000000000000..12ff1c38bd8f --- /dev/null +++ b/platform/util/src/com/intellij/util/NotNullProducer.java @@ -0,0 +1,24 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.util; + +import org.jetbrains.annotations.NotNull; + +public interface NotNullProducer extends Producer { + @Override + @NotNull + T produce(); +} From 4d8960aa7fa187c4ed37fa5a310cbc7672559e59 Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Thu, 15 Mar 2012 12:13:55 +0100 Subject: [PATCH 15/21] AppCode:Debugger: Cannot restart simulator when app was previously on a breakpoint (OC-1322) AppCode:Simulator: starting simulator rewritten to avoid deadlocks and UI blocking --- .../util/src/com/intellij/util/concurrency/FutureResult.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/util/src/com/intellij/util/concurrency/FutureResult.java b/platform/util/src/com/intellij/util/concurrency/FutureResult.java index d5ad8640b416..141b21816886 100644 --- a/platform/util/src/com/intellij/util/concurrency/FutureResult.java +++ b/platform/util/src/com/intellij/util/concurrency/FutureResult.java @@ -2,6 +2,7 @@ package com.intellij.util.concurrency; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; +import org.jetbrains.annotations.Nullable; import java.util.concurrent.*; import java.util.concurrent.Semaphore; @@ -27,7 +28,7 @@ public class FutureResult implements Future { return myValue != null; } - public void set(T result) { + public void set(@Nullable T result) { assert myValue == null; myValue = Ref.create(Pair.create((Object)result, true)); From 56e7e68cc2cef72c927f7f0869f9e947276e262b Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 15 Mar 2012 16:41:55 +0400 Subject: [PATCH 16/21] IDEA-82737 Escape in Live Template to cancel completion popup cancels entire live template --- platform/platform-resources/src/META-INF/LangExtensions.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index e19855dc5a48..235aad239af4 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -581,7 +581,8 @@ - + From 38be73e7143fc7c8924c3320ff72a37732252a1f Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Thu, 15 Mar 2012 16:46:27 +0400 Subject: [PATCH 17/21] IDEA-81112 (Add support for resume-from (-rf) on failed maven builds) Support maven 3. --- .../maven/execution/MavenResumeAction.java | 47 +++++++++++-------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenResumeAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenResumeAction.java index ec96119caa86..ef58e4603d20 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenResumeAction.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenResumeAction.java @@ -119,38 +119,32 @@ public class MavenResumeAction extends AnAction { String text = event.getText().trim(); if (text.isEmpty()) return; + String textWithoutInfo = ""; + if (text.startsWith("[INFO] ")) { + textWithoutInfo = text.substring("[INFO] ".length()).trim(); + } + switch (myState) { case STATE_INITIAL: // initial state. - if (text.equals("[INFO] Reactor build order:")) { + if (textWithoutInfo.equalsIgnoreCase("Reactor build order:")) { myState = STATE_READING_PROJECT_LIST; } break; case STATE_READING_PROJECT_LIST: - if (text.equals("[INFO] ------------------------------------------------------------------------")) { + if (textWithoutInfo.equals("------------------------------------------------------------------------")) { myState = STATE_WAIT_FOR_BUILD; } - else if (text.startsWith("[INFO] ")) { - String projectName = text.substring("[INFO] ".length()); - if (projectName.isEmpty()) { - myState = STATE_WTF; - log("Empty project name in \"Reactor build order\" section!!! other project names: " + myMavenProjectNames); - } - else { - myMavenProjectNames.add(projectName); - } - } - else { - myState = STATE_WTF; - log("\"Reactor build order\" doesn't end by \"-----\"!!! it's end by: " + text); + else if (textWithoutInfo.length() > 0) { + myMavenProjectNames.add(textWithoutInfo); } break; case STATE_WAIT_FOR_BUILD: - if (text.startsWith("[INFO] Building ")) { - String projectName = text.substring("[INFO] Building ".length()); + if (textWithoutInfo.startsWith("Building ")) { + String projectName = textWithoutInfo.substring("Building ".length()); if (myBuildingProjectIndex > myMavenProjectNames.size() || - !myMavenProjectNames.get(myBuildingProjectIndex).equals(projectName)) { + !projectName.startsWith(myMavenProjectNames.get(myBuildingProjectIndex))) { myState = STATE_WTF; log(String.format("Invalid project building order. Defined order: %s, error index: %d, invalid line: %s", myMavenProjectNames, myBuildingProjectIndex, text)); @@ -163,7 +157,7 @@ public class MavenResumeAction extends AnAction { break; case STATE_WAIT_FOR______: - if (text.equals("[INFO] ------------------------------------------------------------------------")) { + if (textWithoutInfo.equals("------------------------------------------------------------------------")) { myState = STATE_WAIT_FOR_BUILD; } break; @@ -216,6 +210,21 @@ public class MavenResumeAction extends AnAction { } } + if (candidate != null) { + return candidate; + } + + for (MavenProject mavenProject : projects) { + if (projectName.equals(mavenProject.getMavenId().getArtifactId())) { + if (candidate == null) { + candidate = mavenProject; + } + else { + return null; + } + } + } + return candidate; } From 9e0294c49e645bf98e9342571bc5013f0e7faabc Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Thu, 15 Mar 2012 16:35:02 +0400 Subject: [PATCH 18/21] Support Git submodules as nested roots Submodules in Git don't have a .git dir. Instead they have .git file referencing to the actual Git repository located in /.git/modules/ To get the .git dir use GitUtil.findGitDir This fixes IDEA-80047 and IDEA-79674 --- plugins/git4idea/src/git4idea/GitUtil.java | 38 +++++++++++++++++++ .../src/git4idea/repo/GitRepository.java | 10 ++++- .../src/git4idea/repo/GitRepositoryFiles.java | 9 ++--- .../git4idea/repo/GitRepositoryUpdater.java | 5 +-- .../repo/GitUntrackedFilesHolder.java | 18 +++++---- 5 files changed, 62 insertions(+), 18 deletions(-) diff --git a/plugins/git4idea/src/git4idea/GitUtil.java b/plugins/git4idea/src/git4idea/GitUtil.java index adcc40604db6..9d21bab8482c 100644 --- a/plugins/git4idea/src/git4idea/GitUtil.java +++ b/plugins/git4idea/src/git4idea/GitUtil.java @@ -48,6 +48,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; +import java.io.IOException; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.util.*; @@ -93,6 +94,43 @@ public class GitUtil { // do nothing } + @Nullable + public static VirtualFile findGitDir(@NotNull VirtualFile rootDir) { + VirtualFile child = rootDir.findChild(".git"); + if (child == null) { + return null; + } + if (child.isDirectory()) { + return child; + } + + // this is standard for submodules, although probably it can + String content = readFile(child); + String pathToDir; + String prefix = "gitdir:"; + if (content.startsWith(prefix)) { + pathToDir = content.substring(prefix.length()).trim(); + } + else { + pathToDir = content; + } + return VcsUtil.getVirtualFile(pathToDir); + } + + @NotNull + private static String readFile(@NotNull VirtualFile file) { + Exception exception = null; + for (int attempts = 0; attempts < 3; attempts++) { + try { + return new String(file.contentsToByteArray()); + } + catch (IOException e) { + exception = e; + } + } + throw new RuntimeException("Couldn't read " + file, exception); + } + /** * Sort files by Git root * diff --git a/plugins/git4idea/src/git4idea/repo/GitRepository.java b/plugins/git4idea/src/git4idea/repo/GitRepository.java index b3d88b4b5efc..12f571199f28 100644 --- a/plugins/git4idea/src/git4idea/repo/GitRepository.java +++ b/plugins/git4idea/src/git4idea/repo/GitRepository.java @@ -26,6 +26,7 @@ import com.intellij.util.messages.MessageBus; import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.messages.Topic; import git4idea.GitBranch; +import git4idea.GitUtil; import git4idea.branch.GitBranchesCollection; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -174,12 +175,12 @@ public final class GitRepository implements Disposable { myProject = project; Disposer.register(parentDisposable, this); - myGitDir = myRootDir.findChild(".git"); + myGitDir = GitUtil.findGitDir(myRootDir); assert myGitDir != null : ".git directory wasn't found under " + rootDir.getPresentableUrl(); myReader = new GitRepositoryReader(VfsUtil.virtualToIoFile(myGitDir)); - myUntrackedFilesHolder = new GitUntrackedFilesHolder(rootDir, project); + myUntrackedFilesHolder = new GitUntrackedFilesHolder(this); Disposer.register(this, myUntrackedFilesHolder); myMessageBus = project.getMessageBus(); @@ -222,6 +223,11 @@ public final class GitRepository implements Disposable { return myRootDir; } + @NotNull + public VirtualFile getGitDir() { + return myGitDir; + } + @NotNull public String getPresentableUrl() { return getRoot().getPresentableUrl(); diff --git a/plugins/git4idea/src/git4idea/repo/GitRepositoryFiles.java b/plugins/git4idea/src/git4idea/repo/GitRepositoryFiles.java index 3dea7f406c29..d4f68bb512f4 100644 --- a/plugins/git4idea/src/git4idea/repo/GitRepositoryFiles.java +++ b/plugins/git4idea/src/git4idea/repo/GitRepositoryFiles.java @@ -45,16 +45,13 @@ public class GitRepositoryFiles { private final String myCommitMessagePath; private final String myExcludePath; - public static GitRepositoryFiles getInstance(@NotNull VirtualFile root) { + public static GitRepositoryFiles getInstance(@NotNull VirtualFile gitDir) { // maybe will be cached later to store a single GitRepositoryFiles for a root. - return new GitRepositoryFiles(root); + return new GitRepositoryFiles(gitDir); } - private GitRepositoryFiles(@NotNull VirtualFile root) { + private GitRepositoryFiles(@NotNull VirtualFile gitDir) { // add .git/ and .git/refs/heads to the VFS - VirtualFile gitDir = root.findChild(".git"); - assert gitDir != null; - // save paths of the files, that we will watch String gitDirPath = GitFileUtils.stripFileProtocolPrefix(gitDir.getPath()); myConfigFilePath = gitDirPath + "/config"; diff --git a/plugins/git4idea/src/git4idea/repo/GitRepositoryUpdater.java b/plugins/git4idea/src/git4idea/repo/GitRepositoryUpdater.java index cce8a02bf5ba..b495b534a295 100644 --- a/plugins/git4idea/src/git4idea/repo/GitRepositoryUpdater.java +++ b/plugins/git4idea/src/git4idea/repo/GitRepositoryUpdater.java @@ -50,11 +50,10 @@ final class GitRepositoryUpdater implements Disposable, BulkFileListener { myRepository = repository; VirtualFile root = repository.getRoot(); - VirtualFile gitDir = root.findChild(".git"); - assert gitDir != null; + VirtualFile gitDir = repository.getGitDir(); LocalFileSystem.getInstance().addRootToWatch(gitDir.getPath(), true); - myRepositoryFiles = GitRepositoryFiles.getInstance(root); + myRepositoryFiles = GitRepositoryFiles.getInstance(gitDir); visitGitDirVfs(gitDir); myHeadsDir = VcsUtil.getVirtualFile(myRepositoryFiles.getRefsHeadsPath()); myRemotesDir = VcsUtil.getVirtualFile(myRepositoryFiles.getRefsRemotesPath()); diff --git a/plugins/git4idea/src/git4idea/repo/GitUntrackedFilesHolder.java b/plugins/git4idea/src/git4idea/repo/GitUntrackedFilesHolder.java index 31d2aee06b2c..356ba991486b 100644 --- a/plugins/git4idea/src/git4idea/repo/GitUntrackedFilesHolder.java +++ b/plugins/git4idea/src/git4idea/repo/GitUntrackedFilesHolder.java @@ -89,14 +89,18 @@ public class GitUntrackedFilesHolder implements Disposable, BulkFileListener { private Set myPossiblyTrackedFiles = new HashSet(); private boolean myReady; // if false, total refresh is needed private final Object LOCK = new Object(); + private final GitRepositoryManager myRepositoryManager; - GitUntrackedFilesHolder(@NotNull VirtualFile root, @NotNull Project project) { - myProject = project; - myRoot = root; - myRepositoryFiles = GitRepositoryFiles.getInstance(root); - myChangeListManager = ChangeListManager.getInstance(project); - myDirtyScopeManager = VcsDirtyScopeManager.getInstance(project); + GitUntrackedFilesHolder(@NotNull GitRepository repository) { + myProject = repository.getProject(); + myRoot = repository.getRoot(); + myChangeListManager = ChangeListManager.getInstance(myProject); + myDirtyScopeManager = VcsDirtyScopeManager.getInstance(myProject); myGit = ServiceManager.getService(Git.class); + + myRepositoryManager = GitUtil.getRepositoryManager(myProject); + assert myRepositoryManager != null; + myRepositoryFiles = GitRepositoryFiles.getInstance(repository.getGitDir()); } void setupVfsListener(@NotNull Project project) { @@ -302,7 +306,7 @@ public class GitUntrackedFilesHolder implements Disposable, BulkFileListener { } private boolean belongsToThisRepository(VirtualFile file) { - final GitRepository repository = GitUtil.getRepositoryManager(myProject).getRepositoryForFile(file); + final GitRepository repository = myRepositoryManager.getRepositoryForFile(file); return repository != null && repository.getRoot().equals(myRoot); } From 95825980c78508b06ed165bad32402b4804ede1f Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Thu, 15 Mar 2012 16:56:07 +0400 Subject: [PATCH 19/21] IDEA-82814 Gradle: do not configure groovy library on a project import if it is already in the project dependencies 1. Refresh the internal structures after the intellij project structure changes implied by the import; 2. Don't perform 'startup refresh on project opening' after the import; --- .../importing/GradleModulesImporter.java | 33 ++++++++++--------- .../importing/GradleProjectImportBuilder.java | 5 +-- .../sync/GradleInitialProjectRefresher.java | 6 +++- .../plugins/gradle/util/GradleConstants.java | 2 ++ 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java index 41c0725e5078..18d7dfe121b8 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java @@ -26,6 +26,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.config.GradleGroovyEnabler; import org.jetbrains.plugins.gradle.config.GradleSettings; import org.jetbrains.plugins.gradle.model.gradle.*; +import org.jetbrains.plugins.gradle.sync.GradleProjectStructureChangesModel; import org.jetbrains.plugins.gradle.task.GradleResolveProjectTask; import org.jetbrains.plugins.gradle.util.GradleBundle; import org.jetbrains.plugins.gradle.util.GradleLog; @@ -318,6 +319,21 @@ public class GradleModulesImporter { finally { writeLock.finish(); } + final GradleSettings settings = GradleSettings.getInstance(intellijProject); + final String gradleHome = settings.getGradleHome(); + if (gradleHome != null) { + final GradleGroovyEnabler groovyEnabler = intellijProject.getComponent(GradleGroovyEnabler.class); + libraryToPreserve.set(groovyEnabler.setupGroovySdkIfNecessary(gradleHome)); + } + + // Force refresh the infrastructure in order to apply newly introduce intellij project structure changes + final GradleProjectStructureChangesModel changesModel = intellijProject.getComponent(GradleProjectStructureChangesModel.class); + if (changesModel != null) { + final GradleProject project = changesModel.getGradleProject(); + if (project != null) { + changesModel.update(project); + } + } } }; @@ -337,21 +353,8 @@ public class GradleModulesImporter { }); } }; - - Runnable setupGroovyTask = new Runnable() { - @Override - public void run() { - final GradleSettings settings = GradleSettings.getInstance(intellijProject); - final String gradleHome = settings.getGradleHome(); - if (gradleHome != null) { - final GradleGroovyEnabler groovyEnabler = intellijProject.getComponent(GradleGroovyEnabler.class); - libraryToPreserve.set(groovyEnabler.setupGroovySdkIfNecessary(gradleHome)); - } - resolveDependenciesTask.run(); - } - }; - - UIUtil.invokeLaterIfNeeded(setupGroovyTask); + + UIUtil.invokeLaterIfNeeded(resolveDependenciesTask); } private static void doSetupLibraries(@NotNull Map moduleMappings, diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleProjectImportBuilder.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleProjectImportBuilder.java index fa12623f17ca..3c65acce4d9f 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleProjectImportBuilder.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleProjectImportBuilder.java @@ -23,6 +23,7 @@ import org.jetbrains.plugins.gradle.model.gradle.GradleModule; import org.jetbrains.plugins.gradle.model.gradle.GradleProject; import org.jetbrains.plugins.gradle.ui.GradleIcons; import org.jetbrains.plugins.gradle.util.GradleBundle; +import org.jetbrains.plugins.gradle.util.GradleConstants; import org.jetbrains.plugins.gradle.util.GradleUtil; import javax.swing.*; @@ -78,8 +79,8 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder commit(final Project project, ModifiableModuleModel model, ModulesProvider modulesProvider, - ModifiableArtifactModel artifactModel) - { + ModifiableArtifactModel artifactModel) { + System.setProperty(GradleConstants.NEWLY_IMPORTED_PROJECT, Boolean.TRUE.toString()); final Runnable task = new Runnable() { @Override public void run() { diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleInitialProjectRefresher.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleInitialProjectRefresher.java index 7f0680d7b1f9..d1fd5d25b6b3 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleInitialProjectRefresher.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleInitialProjectRefresher.java @@ -3,6 +3,7 @@ package org.jetbrains.plugins.gradle.sync; import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.StartupActivity; import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.gradle.util.GradleConstants; import org.jetbrains.plugins.gradle.util.GradleUtil; /** @@ -14,8 +15,11 @@ import org.jetbrains.plugins.gradle.util.GradleUtil; * @since 3/13/12 12:01 PM */ public class GradleInitialProjectRefresher implements StartupActivity { + @SuppressWarnings("UseOfArchaicSystemPropertyAccessors") @Override public void runActivity(@NotNull Project project) { - GradleUtil.refreshProject(project); + if (!Boolean.getBoolean(GradleConstants.NEWLY_IMPORTED_PROJECT)) { + GradleUtil.refreshProject(project); + } } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java index 4e7f2d577923..6f976c121c77 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java @@ -12,6 +12,8 @@ import org.jetbrains.plugins.gradle.ui.GradleProjectStructureNodeDescriptor; */ public class GradleConstants { + @NonNls public static final String NEWLY_IMPORTED_PROJECT = "gradle.newly.imported"; + @NonNls public static final String EXTENSION = "gradle"; @NonNls public static final String DEFAULT_SCRIPT_NAME = "build.gradle"; From c0dcdcd22cc022bd489297567fe08dad104fd063 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Thu, 15 Mar 2012 16:58:30 +0400 Subject: [PATCH 20/21] "Can be null" doesn't imply "is null" --- .../codeInspection/dataFlow/StandardInstructionVisitor.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java index 5ce2fbd6c1f5..ee177909adad 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java @@ -123,7 +123,11 @@ public class StandardInstructionVisitor extends InstructionVisitor { final DfaValue qualifier = memState.pop(); if (instruction.getExpression().isPhysical() && !memState.applyNotNull(qualifier)) { onInstructionProducesNPE(instruction, runner); - return DfaInstructionState.EMPTY_ARRAY; + + if (qualifier instanceof DfaVariableValue) { + final DfaNotNullValue.Factory factory = runner.getFactory().getNotNullFactory(); + memState.setVarValue((DfaVariableValue)qualifier, factory.create(((DfaVariableValue)qualifier).getPsiVariable().getType())); + } } return nextInstruction(instruction, runner, memState); From d165428546b6f9508e35e160336e39f7f9a7f532 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 15 Mar 2012 17:14:23 +0400 Subject: [PATCH 21/21] another fix for too eager casting in completion --- .../completion/JavaCompletionUtil.java | 27 ++++++++++--------- .../normal/InterfaceImplementationNoCast.java | 18 +++++++++++++ .../InterfaceImplementationNoCast_after.java | 18 +++++++++++++ .../completion/NormalCompletionTest.groovy | 1 + 4 files changed, 51 insertions(+), 13 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/normal/InterfaceImplementationNoCast.java create mode 100644 java/java-tests/testData/codeInsight/completion/normal/InterfaceImplementationNoCast_after.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java index 800db37461d2..fb8437096563 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java @@ -504,28 +504,29 @@ public class JavaCompletionUtil { } if (plainQualifier != null) { Object o = item.getObject(); - if (containsMember(plainQualifier, o)) { - if (!(o instanceof PsiMethod)) { - return item; - } + if (o instanceof PsiMethod) { PsiType castType = castTypeItem.getPsiType(); if (plainQualifier instanceof PsiClassType && castType instanceof PsiClassType) { PsiMethod method = (PsiMethod)o; PsiClassType.ClassResolveResult plainResult = ((PsiClassType)plainQualifier).resolveGenerics(); PsiClass plainClass = plainResult.getElement(); - PsiClass castClass = ((PsiClassType)castType).resolveGenerics().getElement(); + if (plainClass != null && plainClass.findMethodBySignature(method, true) != null) { + PsiClass castClass = ((PsiClassType)castType).resolveGenerics().getElement(); - if (castClass == null || plainClass == null || !castClass.isInheritor(plainClass, true)) { - return item; - } + if (castClass == null || !castClass.isInheritor(plainClass, true)) { + return item; + } - PsiSubstitutor plainSub = plainResult.getSubstitutor(); - PsiSubstitutor castSub = TypeConversionUtil.getSuperClassSubstitutor(plainClass, (PsiClassType)castType); - if (method.getSignature(plainSub).equals(method.getSignature(castSub)) && - plainSub.substitute(method.getReturnType()).equals(castSub.substitute(method.getReturnType()))) { - return item; + PsiSubstitutor plainSub = plainResult.getSubstitutor(); + PsiSubstitutor castSub = TypeConversionUtil.getSuperClassSubstitutor(plainClass, (PsiClassType)castType); + if (method.getSignature(plainSub).equals(method.getSignature(castSub)) && + plainSub.substitute(method.getReturnType()).equals(castSub.substitute(method.getReturnType()))) { + return item; + } } } + } else if (containsMember(plainQualifier, o)) { + return item; } } diff --git a/java/java-tests/testData/codeInsight/completion/normal/InterfaceImplementationNoCast.java b/java/java-tests/testData/codeInsight/completion/normal/InterfaceImplementationNoCast.java new file mode 100644 index 000000000000..5f342695a4fe --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/InterfaceImplementationNoCast.java @@ -0,0 +1,18 @@ +public class Util2 { + void foo(XmlAttribute o ) { + if (o instanceof XmlAttributeImpl) { + o.getpar + } + } +} + +interface PsiElement { + PsiElement getParent(); +} +interface XmlAttribute extends PsiElement {} +class XmlAttributeImpl implements XmlAttribute { + @Override + public PsiElement getParent() { + return null; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/normal/InterfaceImplementationNoCast_after.java b/java/java-tests/testData/codeInsight/completion/normal/InterfaceImplementationNoCast_after.java new file mode 100644 index 000000000000..94718eeb8f2e --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/InterfaceImplementationNoCast_after.java @@ -0,0 +1,18 @@ +public class Util2 { + void foo(XmlAttribute o ) { + if (o instanceof XmlAttributeImpl) { + o.getParent() + } + } +} + +interface PsiElement { + PsiElement getParent(); +} +interface XmlAttribute extends PsiElement {} +class XmlAttributeImpl implements XmlAttribute { + @Override + public PsiElement getParent() { + return null; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy index 49f4a214442c..772881af6d50 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy @@ -1325,5 +1325,6 @@ public class ListUtils { } public void testListArrayListCast() { doTest('\n') } + public void testInterfaceImplementationNoCast() { doTest() } }