From 02a04d695da9e8b9b826340f115e038028f5be15 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 26 Jun 2013 11:57:47 +0400 Subject: [PATCH 01/30] one more 'canceled' check --- .../src/com/intellij/util/indexing/FileBasedIndexImpl.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java index 02d91e04a6cf..2d2c5be23acc 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java @@ -2220,6 +2220,10 @@ public class FileBasedIndexImpl extends FileBasedIndex { try { for (VirtualFile file : getAllFilesToUpdate()) { + if (updateSemaphore.isUpdateCanceled()) { + // another thread synchronizing on the same semaphore, got PCE, so throw PCE as well + throw new ProcessCanceledException(); + } if (indexableFilesFilter != null && file instanceof VirtualFileWithId && !indexableFilesFilter.contains(((VirtualFileWithId)file).getId())) { continue; } From 3221b37024d17359ea12315805135bfb3efe768e Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 26 Jun 2013 12:38:41 +0400 Subject: [PATCH 02/30] revert --- .../src/com/intellij/util/indexing/FileBasedIndexImpl.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java index 2d2c5be23acc..02d91e04a6cf 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java @@ -2220,10 +2220,6 @@ public class FileBasedIndexImpl extends FileBasedIndex { try { for (VirtualFile file : getAllFilesToUpdate()) { - if (updateSemaphore.isUpdateCanceled()) { - // another thread synchronizing on the same semaphore, got PCE, so throw PCE as well - throw new ProcessCanceledException(); - } if (indexableFilesFilter != null && file instanceof VirtualFileWithId && !indexableFilesFilter.contains(((VirtualFileWithId)file).getId())) { continue; } From 92980bf622026e7a68347445b0f8003cc7a6109c Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 26 Jun 2013 12:53:42 +0400 Subject: [PATCH 03/30] retry indexing attempt if sibling thread failed to complete indexing because of PCE --- .../util/indexing/FileBasedIndexImpl.java | 79 +++++++++---------- 1 file changed, 39 insertions(+), 40 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java index 02d91e04a6cf..6d8341995f8e 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java @@ -2215,59 +2215,58 @@ public class FileBasedIndexImpl extends FileBasedIndex { private void forceUpdate(@Nullable Project project, @Nullable GlobalSearchScope filter, @Nullable VirtualFile restrictedTo, boolean onlyRemoveOutdatedData) { myChangedFilesCollector.ensureAllInvalidateTasksCompleted(); ProjectIndexableFilesFilter indexableFilesFilter = projectIndexableFiles(project); - - final UpdateSemaphore updateSemaphore = obtainForceUpdateSemaphore(); - try { - for (VirtualFile file : getAllFilesToUpdate()) { - if (indexableFilesFilter != null && file instanceof VirtualFileWithId && !indexableFilesFilter.contains(((VirtualFileWithId)file).getId())) { - continue; + UpdateSemaphore updateSemaphore; + do{ + updateSemaphore = obtainForceUpdateSemaphore(); + try { + for (VirtualFile file : getAllFilesToUpdate()) { + if (indexableFilesFilter != null && file instanceof VirtualFileWithId && !indexableFilesFilter.contains(((VirtualFileWithId)file).getId())) { + continue; + } + + if (filter == null || filter.accept(file) || Comparing.equal(file, restrictedTo)) { + try { + updateSemaphore.down(); + // process only files that can affect result + processFileImpl(project, new com.intellij.ide.caches.FileContent(file), onlyRemoveOutdatedData); + } + catch (ProcessCanceledException e) { + updateSemaphore.reportUpdateCanceled(); + throw e; + } + finally { + updateSemaphore.up(); + } + } } - if (filter == null || filter.accept(file) || Comparing.equal(file, restrictedTo)) { - try { - updateSemaphore.down(); - // process only files that can affect result - processFileImpl(project, new com.intellij.ide.caches.FileContent(file), onlyRemoveOutdatedData); - } - catch (ProcessCanceledException e) { - updateSemaphore.reportUpdateCanceled(); - throw e; - } - finally { - updateSemaphore.up(); + // If several threads entered the method at the same time and there were files to update, + // all the threads should leave the method synchronously after all the files scheduled for update are reindexed, + // no matter which thread will do reindexing job. + // Thus we ensure that all the threads that entered the method will get the most recent data + + while (!updateSemaphore.waitFor(500)) { // may need to wait until another thread is done with indexing + if (Thread.holdsLock(PsiLock.LOCK)) { + break; // hack. Most probably that other indexing threads is waiting for PsiLock, which we're are holding. } } + } - - // If several threads entered the method at the same time and there were files to update, - // all the threads should leave the method synchronously after all the files scheduled for update are reindexed, - // no matter which thread will do reindexing job. - // Thus we ensure that all the threads that entered the method will get the most recent data - - while (!updateSemaphore.waitFor(500)) { // may need to wait until another thread is done with indexing - if (Thread.holdsLock(PsiLock.LOCK)) { - break; // hack. Most probably that other indexing threads is waiting for PsiLock, which we're are holding. - } - } - - if (updateSemaphore.isUpdateCanceled()) { - //System.err.println("cancel index update because of PCE in sibling thread"); - throw new ProcessCanceledException(); - } - + finally { + releaseForceUpdateSemaphore(updateSemaphore); + } + // if some other thread was unable to complete indexing because of PCE, + // we should try again and ensure the file is indexed before proceeding further } - finally { - releaseForceUpdateSemaphore(updateSemaphore); - } - + while (updateSemaphore.isUpdateCanceled()); } private void processFileImpl(Project project, @NotNull final com.intellij.ide.caches.FileContent fileContent, boolean onlyRemoveOutdatedData) { final VirtualFile file = fileContent.getVirtualFile(); final boolean reallyRemoved = myFilesToUpdate.remove(file); if (reallyRemoved && file.isValid()) { - try { + try { if (onlyRemoveOutdatedData || isTooLarge(file)) { // on shutdown there is no need to re-index the file, just remove outdated data from indices final List> affected = new ArrayList>(); From 4ff4fa423ee333dff41e0ea5843c00dbef8590cf Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 26 Jun 2013 11:31:33 +0200 Subject: [PATCH 04/30] IDEA-109177 ('Statement has empty body': inspection ignores comments) --- .../ig/bugs/EmptyStatementBodyInspection.java | 49 +++++++++++++------ .../EmptyStatementBody.html | 6 ++- .../EmptyStatementBody.java | 10 ++++ .../EmptyStatementBodyInspectionTest.java | 1 + 4 files changed, 48 insertions(+), 18 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EmptyStatementBodyInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EmptyStatementBodyInspection.java index 589104585c6a..1408822a314c 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EmptyStatementBodyInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EmptyStatementBodyInspection.java @@ -15,7 +15,7 @@ */ package com.siyeh.ig.bugs; -import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel; +import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel; import com.intellij.psi.*; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; @@ -27,11 +27,12 @@ import javax.swing.*; public class EmptyStatementBodyInspection extends BaseInspection { - /** - * @noinspection PublicField - */ + @SuppressWarnings("PublicField") public boolean m_reportEmptyBlocks = true; + @SuppressWarnings("PublicField") + public boolean commentsAreContent = false; + @Override @NotNull public String getID() { @@ -57,8 +58,10 @@ public class EmptyStatementBodyInspection extends BaseInspection { @Override public JComponent createOptionsPanel() { - return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message("statement.with.empty.body.include.option"), - this, "m_reportEmptyBlocks"); + final MultipleCheckboxOptionsPanel panel = new MultipleCheckboxOptionsPanel(this); + panel.addCheckbox(InspectionGadgetsBundle.message("statement.with.empty.body.include.option"), "m_reportEmptyBlocks"); + panel.addCheckbox(InspectionGadgetsBundle.message("empty.catch.block.comments.option"), "commentsAreContent"); + return panel; } @Override @@ -137,22 +140,36 @@ public class EmptyStatementBodyInspection extends BaseInspection { registerStatementError(statement); } - private boolean isEmpty(PsiElement body) { - if (body instanceof PsiEmptyStatement) { + private boolean isEmpty(PsiElement element) { + if (!commentsAreContent && element instanceof PsiComment) { + return true; + } else if (element instanceof PsiEmptyStatement) { + if (commentsAreContent) { + final PsiElement[] children = element.getChildren(); + for (PsiElement child : children) { + if (child instanceof PsiComment) { + return false; + } + } + } return true; } - else if (body instanceof PsiBlockStatement) { - final PsiBlockStatement block = (PsiBlockStatement)body; + else if (element instanceof PsiWhiteSpace) { + return true; + } + else if (element instanceof PsiBlockStatement) { + final PsiBlockStatement block = (PsiBlockStatement)element; return isEmpty(block.getCodeBlock()); } - else if (m_reportEmptyBlocks && body instanceof PsiCodeBlock) { - final PsiCodeBlock codeBlock = (PsiCodeBlock)body; - final PsiStatement[] statements = codeBlock.getStatements(); - if (statements.length == 0) { + else if (m_reportEmptyBlocks && element instanceof PsiCodeBlock) { + final PsiCodeBlock codeBlock = (PsiCodeBlock)element; + final PsiElement[] children = codeBlock.getChildren(); + if (children.length == 2) { return true; } - for (PsiStatement statement : statements) { - if (!isEmpty(statement)) { + for (int i = 1; i < children.length - 1; i++) { + final PsiElement child = children[i]; + if (!isEmpty(child)) { return false; } } diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyStatementBody.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyStatementBody.html index 1850e1f0f543..376fcd2bf176 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyStatementBody.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyStatementBody.html @@ -5,11 +5,13 @@ Reports if, having empty bodies. While occasionally intended, this construction is confusing, and often the result of a typo.

-At present, this inspection is disabled in JSP files. +This inspection is disabled in JSP files.

-Use the checkbox below to indicate whether this inspection should report statements whose body is an +Use the first checkbox below to indicate whether this inspection should report statements whose body is an empty code block, rather than just empty statements.

+Use the second checkbox below to ignore empty statement bodies which contain a comment. +

Powered by InspectionGadgets \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/empty_statement_body/EmptyStatementBody.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/empty_statement_body/EmptyStatementBody.java index 38f7601b13ab..b4c8652aed19 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/empty_statement_body/EmptyStatementBody.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/empty_statement_body/EmptyStatementBody.java @@ -36,4 +36,14 @@ public class EmptyStatementBody { return true; } + + void comments(boolean b) { + if (b); // comment + while (b) { + // comment + } + do { + ; // comment + } while (b); + } } diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/EmptyStatementBodyInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/EmptyStatementBodyInspectionTest.java index ad29f9e483b4..61b92a429634 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/EmptyStatementBodyInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/EmptyStatementBodyInspectionTest.java @@ -7,6 +7,7 @@ public class EmptyStatementBodyInspectionTest extends IGInspectionTestCase { public void test() throws Exception { final EmptyStatementBodyInspection tool = new EmptyStatementBodyInspection(); tool.m_reportEmptyBlocks = true; + tool.commentsAreContent = true; doTest("com/siyeh/igtest/bugs/empty_statement_body", tool); } } \ No newline at end of file From 8f7120995949a311fbbab7d6f294c4b0d1955809 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 26 Jun 2013 14:03:52 +0400 Subject: [PATCH 05/30] IDEA-77859 (Maven aspect path navigation and completion) --- .../maven/navigator/MavenNavigationUtil.java | 48 +++---------------- 1 file changed, 6 insertions(+), 42 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenNavigationUtil.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenNavigationUtil.java index 38cc7fd355eb..e30c6e789df2 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenNavigationUtil.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenNavigationUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,8 +46,7 @@ import java.io.File; public class MavenNavigationUtil { private static final String ARTIFACT_ID = "artifactId"; - private MavenNavigationUtil() { - } + private MavenNavigationUtil() { } @Nullable public static Navigatable createNavigatableForPom(final Project project, final VirtualFile file) { @@ -82,7 +81,7 @@ public class MavenNavigationUtil { MavenDomProjectModel projectModel = MavenDomUtil.getMavenDomProjectModel(project, file); if (projectModel == null) return; - MavenDomDependency dependency = findDependency(projectModel, artifact); + MavenDomDependency dependency = findDependency(projectModel, artifact.getGroupId(), artifact.getArtifactId()); if (dependency == null) return; XmlTag artifactId = dependency.getArtifactId().getXmlTag(); @@ -91,41 +90,6 @@ public class MavenNavigationUtil { navigate(project, artifactId.getContainingFile().getVirtualFile(), artifactId.getTextOffset() + artifactId.getName().length() + 2, requestFocus); } }; - //final File pom = MavenArtifactUtil.getArtifactFile(myProjectsManager.getLocalRepository(), artifact.getMavenId()); - //final VirtualFile vPom; - //if (pom.exists()) { - //vPom = LocalFileSystem.getInstance().findFileByIoFile(pom); - //} else { - // final MavenProject mp = myProjectsManager.findProject(artifact); - // vPom = mp == null ? null : mp.getFile(); - //} - //if (vPom != null) { - // return new Navigatable.Adapter() { - // public void navigate(boolean requestFocus) { - // int offset = 0; - // try { - // int index = new String(vPom.contentsToByteArray()).indexOf("" + artifact.getArtifactId() + ""); - // if (index != -1) { - // offset += index + 12; - // } - // } - // catch (IOException e) {// - // } - // new OpenFileDescriptor(project, vPom, offset).navigate(requestFocus); - // } - // }; - //} - // - //final Module m = myProjectsManager.findModule(mavenProject); - //if (m == null) return null; - //final OrderEntry e = MavenRootModelAdapter.findLibraryEntry(m, artifact); - //if (e == null) return null; - //return new Navigatable.Adapter() { - // public void navigate(boolean requestFocus) { - // ProjectSettingsService.getInstance(project).openProjectLibrarySettings(new NamedLibraryElement(m, e)); - // } - //}; - } @Nullable @@ -135,14 +99,14 @@ public class MavenNavigationUtil { } @Nullable - public static MavenDomDependency findDependency(@NotNull MavenDomProjectModel projectDom, @NotNull final MavenArtifact artifact) { + public static MavenDomDependency findDependency(@NotNull MavenDomProjectModel projectDom, final String groupId, final String artifactId) { MavenDomProjectProcessorUtils.SearchProcessor processor = new MavenDomProjectProcessorUtils.SearchProcessor() { @Nullable @Override protected MavenDomDependency find(MavenDomDependencies element) { for (MavenDomDependency dependency : element.getDependencies()) { - if (Comparing.equal(artifact.getGroupId(), dependency.getGroupId().getStringValue()) - && Comparing.equal(artifact.getArtifactId(), dependency.getArtifactId().getStringValue())) { + if (Comparing.equal(groupId, dependency.getGroupId().getStringValue()) && + Comparing.equal(artifactId, dependency.getArtifactId().getStringValue())) { return dependency; } } From 2c3d4372c2a46a50799ef7e36ea90c1ce44223d6 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 26 Jun 2013 14:07:08 +0400 Subject: [PATCH 06/30] move to upper level --- .../util/indexing/FileBasedIndexImpl.java | 15 -------- .../util/indexing/UpdateSemaphore.java | 37 +++++++++++++++++++ 2 files changed, 37 insertions(+), 15 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/util/indexing/UpdateSemaphore.java diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java index 6d8341995f8e..3a0ef9e48708 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java @@ -2288,21 +2288,6 @@ public class FileBasedIndexImpl extends FileBasedIndex { } } - private static final class UpdateSemaphore extends Semaphore { - private volatile boolean myIsCanceled = false; - - UpdateSemaphore() { - } - - boolean isUpdateCanceled() { - return myIsCanceled; - } - - void reportUpdateCanceled() { - myIsCanceled = true; - } - } - private class UnindexedFilesFinder implements CollectingContentIterator { private final List myFiles = new ArrayList(); @Nullable diff --git a/platform/lang-impl/src/com/intellij/util/indexing/UpdateSemaphore.java b/platform/lang-impl/src/com/intellij/util/indexing/UpdateSemaphore.java new file mode 100644 index 000000000000..41106064760a --- /dev/null +++ b/platform/lang-impl/src/com/intellij/util/indexing/UpdateSemaphore.java @@ -0,0 +1,37 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.util.indexing; + +import com.intellij.util.concurrency.Semaphore; + +/** +* @author Eugene Zhuravlev +* Date: 6/26/13 +*/ +final class UpdateSemaphore extends Semaphore { + private volatile boolean myIsCanceled = false; + + UpdateSemaphore() { + } + + boolean isUpdateCanceled() { + return myIsCanceled; + } + + void reportUpdateCanceled() { + myIsCanceled = true; + } +} From 0c314f441fca134a3ca5574047b0ea5c06b46c57 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 26 Jun 2013 12:22:32 +0200 Subject: [PATCH 07/30] IDEA-109609 undo/redo is not working if file located in excluded directory --- .../src/com/intellij/psi/SingleRootFileViewProvider.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java b/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java index a8c94f3545f1..37ba5ed09ba8 100644 --- a/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java +++ b/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java @@ -47,6 +47,7 @@ import com.intellij.testFramework.LightVirtualFile; import com.intellij.util.LocalTimeCounter; import com.intellij.util.ReflectionCache; import com.intellij.util.SmartList; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -146,7 +147,7 @@ public class SingleRootFileViewProvider extends UserDataHolderBase implements Fi @Override @NotNull public List getAllFiles() { - return Collections.singletonList(getPsi(getBaseLanguage())); + return ContainerUtil.createMaybeSingletonList(getPsi(getBaseLanguage())); } @Nullable From 0fd94d71e11b5d41564e18a858c6197f9c8081a6 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 26 Jun 2013 13:13:19 +0200 Subject: [PATCH 08/30] empty statement counts as empty --- .../EmptyCatchBlockInspection.java | 74 +++++++++-------- .../EmptyCatchBlockInspection.java | 23 ------ .../EmptyCatchBlockInspectionInTestCase.java | 25 ------ .../EmptyCatchBlockInspectionTest.java | 80 +++++++++++++++++++ 4 files changed, 120 insertions(+), 82 deletions(-) delete mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/exceptionHandling/EmptyCatchBlockInspection.java delete mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/exceptionHandling/EmptyCatchBlockInspectionInTestCase.java create mode 100644 plugins/InspectionGadgets/testsrc/com/siyeh/ig/errorhandling/EmptyCatchBlockInspectionTest.java diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyCatchBlockInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyCatchBlockInspection.java index 479513f99eaa..bb6cf98be80c 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyCatchBlockInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyCatchBlockInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 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. @@ -20,7 +20,6 @@ import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.util.PsiUtil; -import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; @@ -51,15 +50,13 @@ public class EmptyCatchBlockInspection extends BaseInspection { @Override @NotNull public String getDisplayName() { - return InspectionGadgetsBundle.message( - "empty.catch.block.display.name"); + return InspectionGadgetsBundle.message("empty.catch.block.display.name"); } @Override @NotNull protected String buildErrorString(Object... infos) { - return InspectionGadgetsBundle.message( - "empty.catch.block.problem.descriptor"); + return InspectionGadgetsBundle.message("empty.catch.block.problem.descriptor"); } @Override @@ -69,15 +66,10 @@ public class EmptyCatchBlockInspection extends BaseInspection { @Override public JComponent createOptionsPanel() { - final MultipleCheckboxOptionsPanel optionsPanel = - new MultipleCheckboxOptionsPanel(this); - optionsPanel.addCheckbox(InspectionGadgetsBundle.message( - "empty.catch.block.comments.option"), "m_includeComments"); - optionsPanel.addCheckbox(InspectionGadgetsBundle.message( - "empty.catch.block.ignore.option"), "m_ignoreTestCases"); - optionsPanel.addCheckbox(InspectionGadgetsBundle.message( - "empty.catch.block.ignore.ignore.option"), - "m_ignoreIgnoreParameter"); + final MultipleCheckboxOptionsPanel optionsPanel = new MultipleCheckboxOptionsPanel(this); + optionsPanel.addCheckbox(InspectionGadgetsBundle.message("empty.catch.block.comments.option"), "m_includeComments"); + optionsPanel.addCheckbox(InspectionGadgetsBundle.message("empty.catch.block.ignore.option"), "m_ignoreTestCases"); + optionsPanel.addCheckbox(InspectionGadgetsBundle.message("empty.catch.block.ignore.ignore.option"), "m_ignoreIgnoreParameter"); return optionsPanel; } @@ -92,13 +84,11 @@ public class EmptyCatchBlockInspection extends BaseInspection { @Override @NotNull public String getName() { - return InspectionGadgetsBundle.message( - "rename.catch.parameter.to.ignored"); + return InspectionGadgetsBundle.message("rename.catch.parameter.to.ignored"); } @Override - protected void doFix(Project project, ProblemDescriptor descriptor) - throws IncorrectOperationException { + protected void doFix(Project project, ProblemDescriptor descriptor) { final PsiElement element = descriptor.getPsiElement(); final PsiElement parent = element.getParent(); if (!(parent instanceof PsiCatchSection)) { @@ -113,10 +103,8 @@ public class EmptyCatchBlockInspection extends BaseInspection { if (identifier == null) { return; } - final PsiElementFactory factory = - JavaPsiFacade.getInstance(project).getElementFactory(); - final PsiIdentifier newIdentifier = - factory.createIdentifier("ignored"); + final PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); + final PsiIdentifier newIdentifier = factory.createIdentifier("ignored"); identifier.replace(newIdentifier); } } @@ -145,7 +133,7 @@ public class EmptyCatchBlockInspection extends BaseInspection { private void checkCatchSection(PsiCatchSection section) { final PsiCodeBlock block = section.getCatchBlock(); - if (block == null || !isCatchBlockEmpty(block)) { + if (block == null || !isEmpty(block)) { return; } final PsiParameter parameter = section.getParameter(); @@ -167,21 +155,39 @@ public class EmptyCatchBlockInspection extends BaseInspection { registerError(catchToken); } - private boolean isCatchBlockEmpty(PsiCodeBlock block) { - if (m_includeComments) { - final PsiElement[] children = block.getChildren(); - for (final PsiElement child : children) { - if (child instanceof PsiComment || - child instanceof PsiStatement) { + private boolean isEmpty(PsiElement element) { + if (!m_includeComments && element instanceof PsiComment) { + return true; + } else if (element instanceof PsiEmptyStatement) { + if (m_includeComments) { + final PsiElement[] children = element.getChildren(); + for (PsiElement child : children) { + if (child instanceof PsiComment) { + return false; + } + } + } + return true; + } else if (element instanceof PsiWhiteSpace) { + return true; + } else if (element instanceof PsiBlockStatement) { + final PsiBlockStatement block = (PsiBlockStatement)element; + return isEmpty(block.getCodeBlock()); + } else if (element instanceof PsiCodeBlock) { + final PsiCodeBlock codeBlock = (PsiCodeBlock)element; + final PsiElement[] children = codeBlock.getChildren(); + if (children.length == 2) { + return true; + } + for (int i = 1; i < children.length - 1; i++) { + final PsiElement child = children[i]; + if (!isEmpty(child)) { return false; } } return true; } - else { - final PsiStatement[] statements = block.getStatements(); - return statements.length == 0; - } + return false; } } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/exceptionHandling/EmptyCatchBlockInspection.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/exceptionHandling/EmptyCatchBlockInspection.java deleted file mode 100644 index b03a0247fbea..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/exceptionHandling/EmptyCatchBlockInspection.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.siyeh.igtest.exceptionHandling; - -public class EmptyCatchBlockInspection -{ - public void foo() - { - try - { - throw new Exception(); - } - catch(Exception e) - { - } - try - { - throw new Exception(); - } - catch(Exception e) - { - //catch comment - } - } -} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/exceptionHandling/EmptyCatchBlockInspectionInTestCase.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/exceptionHandling/EmptyCatchBlockInspectionInTestCase.java deleted file mode 100644 index b79d71a19032..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/exceptionHandling/EmptyCatchBlockInspectionInTestCase.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.siyeh.igtest.exceptionHandling; - -import junit.framework.TestCase; - -public class EmptyCatchBlockInspectionInTestCase extends TestCase -{ - public void foo() - { - try - { - throw new Exception(); - } - catch(Exception e) - { - } - try - { - throw new Exception(); - } - catch(Exception e) - { - //catch comment - } - } -} diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/errorhandling/EmptyCatchBlockInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/errorhandling/EmptyCatchBlockInspectionTest.java new file mode 100644 index 000000000000..5648d5733e31 --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/errorhandling/EmptyCatchBlockInspectionTest.java @@ -0,0 +1,80 @@ +package com.siyeh.ig.errorhandling; + +import com.intellij.codeInspection.LocalInspectionTool; +import com.siyeh.ig.LightInspectionTestCase; + +public class EmptyCatchBlockInspectionTest extends LightInspectionTestCase { + + @Override + protected LocalInspectionTool getInspection() { + final EmptyCatchBlockInspection tool = new EmptyCatchBlockInspection(); + tool.m_includeComments = true; + tool.m_ignoreTestCases = true; + tool.m_ignoreIgnoreParameter = true; + return tool; + } + + @Override + protected String[] getEnvironmentClasses() { + return new String[] { + "package junit.framework; public abstract class TestCase {}" + }; + } + + public void testSimple() { + doTest("class C {\n" + + " void m() {\n" + + " try {\n" + + " throw new Exception();\n" + + " } /*Empty 'catch' block*/catch/**/ (Exception e) {\n" + + " }\n" + + " }\n" + + "}\n"); + } + + public void testEmptyStatement() { + doTest("class C {\n" + + " void m() {\n" + + " try {\n" + + " throw new Exception();\n" + + " } /*Empty 'catch' block*/catch/**/ (Exception e) {\n" + + " ;\n" + + " }\n" + + " }\n" + + "}\n"); + } + + public void testComment() { + doTest("class C {\n" + + " void m() {\n" + + " try {\n" + + " throw new Exception();\n" + + " } catch (Exception e) {\n" + + " // comment\n" + + " }\n" + + " }\n" + + "}\n"); + } + + public void testIgnored() { + doTest("class C {\n" + + " void m() {\n" + + " try {\n" + + " throw new Exception();\n" + + " } catch (Exception ignored) {\n" + + " }\n" + + " }\n" + + "}\n"); + } + + public void testTest() { + doTest("import junit.framework.TestCase;\n" + + "class C extends TestCase {\n" + + " void m() {\n" + + " try {\n" + + " throw new Exception();\n" + + " } catch (Exception e) {}\n" + + " }\n" + + "}\n"); + } +} From 064b30f67b85df8010ad2326827bd5f94e0b068b Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 26 Jun 2013 13:14:00 +0200 Subject: [PATCH 09/30] use PsiUtil.isIgnoredName() --- .../ExceptionFromCatchWhichDoesntWrapInspection.java | 5 +++-- .../ig/errorhandling/UnusedCatchParameterInspection.java | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/ExceptionFromCatchWhichDoesntWrapInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/ExceptionFromCatchWhichDoesntWrapInspection.java index 3b609c93c56e..bc9264508efb 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/ExceptionFromCatchWhichDoesntWrapInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/ExceptionFromCatchWhichDoesntWrapInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 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. @@ -19,6 +19,7 @@ import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel; import com.intellij.psi.*; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; import com.intellij.util.Processor; import com.intellij.util.Query; import com.siyeh.InspectionGadgetsBundle; @@ -87,7 +88,7 @@ public class ExceptionFromCatchWhichDoesntWrapInspection extends BaseInspection return; } @NonNls final String parameterName = parameter.getName(); - if ("ignore".equals(parameterName) || "ignored".equals(parameterName)) { + if (PsiUtil.isIgnoredName(parameterName)) { return; } final PsiExpression exception = statement.getException(); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/UnusedCatchParameterInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/UnusedCatchParameterInspection.java index 7d68417d133d..d217e842bf0b 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/UnusedCatchParameterInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/UnusedCatchParameterInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 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. @@ -17,6 +17,7 @@ package com.siyeh.ig.errorhandling; import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel; import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; @@ -108,7 +109,6 @@ public class UnusedCatchParameterInspection extends BaseInspection { return; } @NonNls final String parameterName = parameter.getName(); - final boolean namedIgnore = parameterName.contains("ignore"); final PsiCodeBlock block = section.getCatchBlock(); if (block == null) { return; @@ -124,6 +124,7 @@ public class UnusedCatchParameterInspection extends BaseInspection { final CatchParameterUsedVisitor visitor = new CatchParameterUsedVisitor(parameter); block.accept(visitor); + final boolean namedIgnore = PsiUtil.isIgnoredName(parameterName); if (visitor.isUsed()) { if (namedIgnore) { registerVariableError(parameter, Boolean.valueOf(true)); From a37ee925f42cbec4ec5ce496e18c925c25967c0f Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Wed, 26 Jun 2013 14:41:59 +0400 Subject: [PATCH 10/30] RUBY-13855: @NotNull added --- .../src/com/intellij/openapi/components/PathMacroMap.java | 7 ++++--- .../com/intellij/openapi/components/PathMacroManager.java | 4 ++-- .../openapi/components/impl/BasePathMacroManager.java | 5 +++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/jps/model-serialization/src/com/intellij/openapi/components/PathMacroMap.java b/jps/model-serialization/src/com/intellij/openapi/components/PathMacroMap.java index c0484d6299fa..05dc780d2e07 100644 --- a/jps/model-serialization/src/com/intellij/openapi/components/PathMacroMap.java +++ b/jps/model-serialization/src/com/intellij/openapi/components/PathMacroMap.java @@ -22,6 +22,7 @@ import org.jdom.Attribute; import org.jdom.Comment; import org.jdom.Element; import org.jdom.Text; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -36,11 +37,11 @@ public abstract class PathMacroMap { public abstract String substitute(String text, boolean caseSensitive); - public final void substitute(Element e, boolean caseSensitive) { + public final void substitute(@NotNull Element e, boolean caseSensitive) { substitute(e, caseSensitive, false); } - public final void substitute(Element e, boolean caseSensitive, final boolean recursively, + public final void substitute(@NotNull Element e, boolean caseSensitive, final boolean recursively, @Nullable PathMacroFilter filter) { List content = e.getContent(); //noinspection ForLoopReplaceableByForEach @@ -77,7 +78,7 @@ public abstract class PathMacroMap { } } - public final void substitute(Element e, boolean caseSensitive, final boolean recursively) { + public final void substitute(@NotNull Element e, boolean caseSensitive, final boolean recursively) { substitute(e, caseSensitive, recursively, null); } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/PathMacroManager.java b/platform/projectModel-impl/src/com/intellij/openapi/components/PathMacroManager.java index 8e8d484e16d7..29cbcb573df9 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/components/PathMacroManager.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/components/PathMacroManager.java @@ -26,12 +26,12 @@ public abstract class PathMacroManager implements PathMacroSubstitutor { } @Override - public abstract void expandPaths(Element element); + public abstract void expandPaths(@NotNull Element element); @Override public abstract void collapsePaths(Element element); - public abstract void collapsePathsRecursively(Element element); + public abstract void collapsePathsRecursively(@NotNull Element element); public abstract String collapsePathsRecursively(String text); diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/BasePathMacroManager.java b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/BasePathMacroManager.java index 47e409329072..49b94cac0f79 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/BasePathMacroManager.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/BasePathMacroManager.java @@ -30,6 +30,7 @@ import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.VirtualFileSystem; import com.intellij.util.containers.FactoryMap; import org.jdom.Element; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.serialization.PathMacroUtil; @@ -111,7 +112,7 @@ public class BasePathMacroManager extends PathMacroManager { } @Override - public void collapsePathsRecursively(final Element element) { + public void collapsePathsRecursively(@NotNull final Element element) { getReplacePathMap().substitute(element, SystemInfo.isFileSystemCaseSensitive, true); } @@ -121,7 +122,7 @@ public class BasePathMacroManager extends PathMacroManager { } @Override - public void expandPaths(final Element element) { + public void expandPaths(@NotNull final Element element) { getExpandMacroMap().substitute(element, SystemInfo.isFileSystemCaseSensitive); } From 9adc928cc46b61ce5693c0d875c9876807acd14f Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 26 Jun 2013 12:56:47 +0400 Subject: [PATCH 11/30] implement method fix from incomplete statement fix (IDEA-109540) --- .../impl/analysis/HighlightClassUtil.java | 20 ++++++++------- .../impl/quickfix/ImplementMethodsFix.java | 12 +++++---- .../generation/OverrideImplementUtil.java | 25 +++++++++++-------- .../OverrideImplementExploreUtil.java | 2 +- 4 files changed, 33 insertions(+), 26 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java index 5bcc31079aab..db361e588d61 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java @@ -55,10 +55,7 @@ import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; +import java.util.*; public class HighlightClassUtil { private static final QuickFixFactory QUICK_FIX_FACTORY = QuickFixFactory.getInstance(); @@ -1012,12 +1009,17 @@ public class HighlightClassUtil { newExpression = (PsiNewExpression)startElement.replace(newExpression); final PsiClass psiClass = newExpression.getAnonymousClass(); if (psiClass == null) return; - PsiClassType baseClassType = ((PsiAnonymousClass)psiClass).getBaseClassType(); - PsiClass resolve = baseClassType.resolve(); - if (resolve == null) return; - PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(resolve, psiClass, PsiSubstitutor.EMPTY); + Map subst = new HashMap(); for (PsiMethodMember selectedElement : selectedElements) { - selectedElement.setSubstitutor(superClassSubstitutor); + final PsiClass baseClass = selectedElement.getElement().getContainingClass(); + if (baseClass != null) { + PsiSubstitutor substitutor = subst.get(baseClass); + if (substitutor == null) { + substitutor = TypeConversionUtil.getSuperClassSubstitutor(baseClass, psiClass, PsiSubstitutor.EMPTY); + subst.put(baseClass, substitutor); + } + selectedElement.setSubstitutor(substitutor); + } } OverrideImplementUtil.overrideOrImplementMethodsInRightPlace(editor, psiClass, selectedElements, chooser.isCopyJavadoc(), chooser.isInsertOverrideAnnotation()); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementMethodsFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementMethodsFix.java index f9c9b7b7373c..a09213fd8441 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementMethodsFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementMethodsFix.java @@ -28,15 +28,17 @@ import com.intellij.openapi.application.Result; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiEnumConstant; -import com.intellij.psi.PsiFile; +import com.intellij.psi.*; import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.containers.ContainerUtil; +import net.sf.cglib.core.CollectionUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; import java.util.List; public class ImplementMethodsFix extends LocalQuickFixAndIntentionActionOnPsiElement { @@ -107,6 +109,6 @@ public class ImplementMethodsFix extends LocalQuickFixAndIntentionActionOnPsiEle FeatureUsageTracker.getInstance().triggerFeatureUsed(ProductivityFeatureNames.CODEASSISTS_OVERRIDE_IMPLEMENT); return OverrideImplementUtil - .showOverrideImplementChooser(editor, startElement, true, OverrideImplementExploreUtil.getMethodsToOverrideImplement(aClass, true), Collections.emptyList()); + .showOverrideImplementChooser(editor, startElement, true, OverrideImplementExploreUtil.getMethodsToOverrideImplement(aClass, true), ContainerUtil.newArrayList()); } } diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java index 4f45ac344e73..53630f602ef1 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java @@ -435,17 +435,6 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil { Collection secondary = toImplement || aClass.isInterface() ? ContainerUtil.newArrayList() : getMethodsToOverrideImplement(aClass, true); - if (toImplement && PsiUtil.isLanguageLevel8OrHigher(aClass)) { - for (Iterator iterator = candidates.iterator(); iterator.hasNext(); ) { - CandidateInfo candidate = iterator.next(); - PsiElement element = candidate.getElement(); - if (element instanceof PsiMethod && ((PsiMethod)element).hasModifierProperty(PsiModifier.DEFAULT)) { - iterator.remove(); - secondary.add(candidate); - } - } - } - final MemberChooser chooser = showOverrideImplementChooser(editor, aClass, toImplement, candidates, secondary); if (chooser == null) return; @@ -461,6 +450,9 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil { }.execute(); } + /** + * @param candidates, secondary should allow modifications + */ @Nullable public static MemberChooser showOverrideImplementChooser(Editor editor, final PsiElement aClass, @@ -468,6 +460,17 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil { final Collection candidates, Collection secondary) { + if (toImplement && PsiUtil.isLanguageLevel8OrHigher(aClass)) { + for (Iterator iterator = candidates.iterator(); iterator.hasNext(); ) { + CandidateInfo candidate = iterator.next(); + PsiElement element = candidate.getElement(); + if (element instanceof PsiMethod && ((PsiMethod)element).hasModifierProperty(PsiModifier.DEFAULT)) { + iterator.remove(); + secondary.add(candidate); + } + } + } + final JavaOverrideImplementMemberChooser chooser = JavaOverrideImplementMemberChooser.create(aClass, toImplement, candidates, secondary); if (chooser == null) { diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/generation/OverrideImplementExploreUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/generation/OverrideImplementExploreUtil.java index d89cce536e6d..c80c8935b649 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/generation/OverrideImplementExploreUtil.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/generation/OverrideImplementExploreUtil.java @@ -55,7 +55,7 @@ public class OverrideImplementExploreUtil { continue; } // filter already implemented - if (MethodSignatureUtil.findMethodBySignature(aClass, signature, false) != null) { + if (aClass != hisClass && MethodSignatureUtil.findMethodBySignature(aClass, signature, false) != null) { continue; } From d4fc0336159ce3dfabb1cf7dfc9af17300bb4df6 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 26 Jun 2013 15:24:14 +0400 Subject: [PATCH 12/30] javafx: support propertyProperty rename/delete (IDEA-109574) --- .../GetterSetterPrototypeProvider.java | 35 +++++++++++ .../rename/RenameJavaVariableProcessor.java | 61 ++++++++++++------- .../safeDelete/JavaSafeDeleteProcessor.java | 24 +++++--- .../plugins/javaFX/RefactoringFieldTest.java | 60 ++++++++++++++++++ .../JavaFxGetterSetterPrototypeProvider.java | 22 +++++++ .../fieldRefactoring/PropertyDelete.java | 18 ++++++ .../PropertyDelete_after.java | 6 ++ .../fieldRefactoring/PropertyRename.java | 18 ++++++ .../PropertyRename_after.java | 18 ++++++ 9 files changed, 232 insertions(+), 30 deletions(-) create mode 100644 plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/RefactoringFieldTest.java create mode 100644 plugins/javaFX/testData/fieldRefactoring/PropertyDelete.java create mode 100644 plugins/javaFX/testData/fieldRefactoring/PropertyDelete_after.java create mode 100644 plugins/javaFX/testData/fieldRefactoring/PropertyRename.java create mode 100644 plugins/javaFX/testData/fieldRefactoring/PropertyRename_after.java diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GetterSetterPrototypeProvider.java b/java/java-impl/src/com/intellij/codeInsight/generation/GetterSetterPrototypeProvider.java index 727bd8143dd9..521445725ef0 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GetterSetterPrototypeProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GetterSetterPrototypeProvider.java @@ -17,6 +17,7 @@ package com.intellij.codeInsight.generation; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; +import com.intellij.psi.PsiClass; import com.intellij.psi.PsiField; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiModifier; @@ -31,6 +32,17 @@ public abstract class GetterSetterPrototypeProvider { public abstract boolean canGeneratePrototypeFor(PsiField field); public abstract PsiMethod[] generateGetters(PsiField field); public abstract PsiMethod[] generateSetters(PsiField field); + public PsiMethod[] findGetters(PsiClass psiClass, String propertyName) { + return null; + } + + public String suggestGetterName(String propertyName) { + return null; + } + + public boolean isSimpleGetter(PsiMethod method, String oldPropertyName) { + return false; + } public abstract boolean isReadOnly(PsiField field); @@ -51,4 +63,27 @@ public abstract class GetterSetterPrototypeProvider { } return field.hasModifierProperty(PsiModifier.FINAL); } + + public static PsiMethod[] findGetters(PsiClass aClass, String propertyName, boolean isStatic) { + if (!isStatic) { + for (GetterSetterPrototypeProvider provider : Extensions.getExtensions(EP_NAME)) { + final PsiMethod[] getterSetter = provider.findGetters(aClass, propertyName); + if (getterSetter != null) return getterSetter; + } + } + final PsiMethod propertyGetterSetter = PropertyUtil.findPropertyGetter(aClass, propertyName, isStatic, false); + if (propertyGetterSetter != null) { + return new PsiMethod[] {propertyGetterSetter}; + } + return null; + } + + public static String suggestNewGetterName(String oldPropertyName, String newPropertyName, PsiMethod method) { + for (GetterSetterPrototypeProvider provider : Extensions.getExtensions(EP_NAME)) { + if (provider.isSimpleGetter(method, oldPropertyName)) { + return provider.suggestGetterName(newPropertyName); + } + } + return null; + } } diff --git a/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java b/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java index 7e485dc00ca3..8c2f68887c71 100644 --- a/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java @@ -15,6 +15,7 @@ */ package com.intellij.refactoring.rename; +import com.intellij.codeInsight.generation.GetterSetterPrototypeProvider; import com.intellij.lang.StdLanguages; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; @@ -43,10 +44,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.util.*; public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor { private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.RenameJavaVariableProcessor"); @@ -150,7 +148,9 @@ public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor { String newPropertyName = manager.variableNameToPropertyName(newName, VariableKind.FIELD); boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC); - PsiMethod getter = PropertyUtil.findPropertyGetter(aClass, propertyName, isStatic, false); + + PsiMethod[] getters = GetterSetterPrototypeProvider.findGetters(aClass, propertyName, isStatic); + PsiMethod setter = PropertyUtil.findPropertySetter(aClass, propertyName, isStatic, false); boolean shouldRenameSetterParameter = false; @@ -161,22 +161,31 @@ public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor { shouldRenameSetterParameter = parameterName.equals(setterParameter.getName()); } - String newGetterName = ""; - - if (getter != null) { - String getterId = getter.getName(); - newGetterName = PropertyUtil.suggestGetterName(newPropertyName, field.getType(), getterId); - if (newGetterName.equals(getterId)) { - getter = null; - newGetterName = null; - } else { - for (PsiMethod method : getter.findDeepestSuperMethods()) { - if (method instanceof PsiCompiledElement) { - getter = null; - break; - } + if (getters != null) { + List validGetters = new ArrayList(); + for (PsiMethod getter : getters) { + String newGetterName = GetterSetterPrototypeProvider.suggestNewGetterName(propertyName, newPropertyName, getter); + String getterId = null; + if (newGetterName == null) { + getterId = getter.getName(); + newGetterName = PropertyUtil.suggestGetterName(newPropertyName, field.getType(), getterId); } + if (newGetterName.equals(getterId)) { + continue; + } + else { + boolean valid = true; + for (PsiMethod method : getter.findDeepestSuperMethods()) { + if (method instanceof PsiCompiledElement) { + valid = false; + break; + } + } + if (!valid) continue; + } + validGetters.add(getter); } + getters = validGetters.isEmpty() ? null : validGetters.toArray(new PsiMethod[validGetters.size()]); } String newSetterName = ""; @@ -201,14 +210,20 @@ public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor { } } - if ((getter != null || setter != null) && askToRenameAccesors(getter, setter, newName, project)) { - getter = null; + if ((getters != null || setter != null) && askToRenameAccesors(getters != null ? getters[0] : null, setter, newName, project)) { + getters = null; setter = null; shouldRenameSetterParameter = false; } - if (getter != null) { - addOverriddenAndImplemented(getter, newGetterName, allRenames); + if (getters != null) { + for (PsiMethod getter : getters) { + String newGetterName = GetterSetterPrototypeProvider.suggestNewGetterName(propertyName, newPropertyName, getter); + if (newGetterName == null) { + newGetterName = PropertyUtil.suggestGetterName(newPropertyName, field.getType(), getter.getName()); + } + addOverriddenAndImplemented(getter, newGetterName, allRenames); + } } if (setter != null) { diff --git a/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java b/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java index 7f8ae6d46b99..ac7a6d9ece69 100644 --- a/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java @@ -16,6 +16,7 @@ package com.intellij.refactoring.safeDelete; import com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableUtil; +import com.intellij.codeInsight.generation.GetterSetterPrototypeProvider; import com.intellij.find.findUsages.PsiElement2UsageTargetAdapter; import com.intellij.ide.util.SuperMethodWarningUtil; import com.intellij.openapi.application.ApplicationManager; @@ -187,21 +188,30 @@ public class JavaSafeDeleteProcessor extends SafeDeleteProcessorDelegateBase { PsiClass aClass = field.getContainingClass(); if (aClass != null) { boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC); - PsiMethod getter = PropertyUtil.findPropertyGetter(aClass, propertyName, isStatic, false); - if (allElementsToDelete.contains(getter) || getter != null && !getter.isPhysical()) getter = null; + PsiMethod[] getters = GetterSetterPrototypeProvider.findGetters(aClass, propertyName, isStatic); + if (getters != null) { + final List validGetters = new ArrayList(1); + for (PsiMethod getter : getters) { + if (!allElementsToDelete.contains(getter) && (getter != null && getter.isPhysical())) { + validGetters.add(getter); + } + } + getters = validGetters.isEmpty() ? null : validGetters.toArray(new PsiMethod[validGetters.size()]); + } + PsiMethod setter = PropertyUtil.findPropertySetter(aClass, propertyName, isStatic, false); if (allElementsToDelete.contains(setter) || setter != null && !setter.isPhysical()) setter = null; - if (askUser && (getter != null || setter != null)) { + if (askUser && (getters != null || setter != null)) { final String message = - RefactoringMessageUtil.getGetterSetterMessage(field.getName(), RefactoringBundle.message("delete.title"), getter, setter); - if (Messages.showYesNoDialog(project, message, RefactoringBundle.message("safe.delete.title"), Messages.getQuestionIcon()) != 0) { - getter = null; + RefactoringMessageUtil.getGetterSetterMessage(field.getName(), RefactoringBundle.message("delete.title"), getters != null ? getters[0] : null, setter); + if (!ApplicationManager.getApplication().isUnitTestMode() && Messages.showYesNoDialog(project, message, RefactoringBundle.message("safe.delete.title"), Messages.getQuestionIcon()) != 0) { + getters = null; setter = null; } } List elements = new ArrayList(); if (setter != null) elements.add(setter); - if (getter != null) elements.add(getter); + if (getters != null) Collections.addAll(elements, getters); return elements; } } diff --git a/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/RefactoringFieldTest.java b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/RefactoringFieldTest.java new file mode 100644 index 000000000000..5ac15b3f8977 --- /dev/null +++ b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/RefactoringFieldTest.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.plugins.javaFX; + +import com.intellij.codeInsight.TargetElementUtilBase; +import com.intellij.openapi.application.PluginPathManager; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.rename.RenameProcessor; +import com.intellij.refactoring.safeDelete.SafeDeleteHandler; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.javaFX.fxml.AbstractJavaFXTestCase; + +public class RefactoringFieldTest extends AbstractJavaFXTestCase { + + public void testPropertyRename() throws Exception { + myFixture.configureByFile(getTestName(false) + ".java"); + performRename("newName"); + myFixture.checkResultByFile(getTestName(false) + "_after.java"); + } + + public void testPropertyDelete() throws Exception { + myFixture.configureByFile(getTestName(false) + ".java"); + performDelete(); + myFixture.checkResultByFile(getTestName(false) + "_after.java"); + } + + protected void performRename(String newName) { + PsiElement element = TargetElementUtilBase.findTargetElement(myFixture.getEditor(), TargetElementUtilBase + .ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED); + + new RenameProcessor(getProject(), element, newName, false, false).run(); + } + + private void performDelete() { + final PsiElement psiElement = TargetElementUtilBase + .findTargetElement(myFixture.getEditor(), TargetElementUtilBase.ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED); + assertNotNull("No element found in text:\n" + myFixture.getFile().getText(), psiElement); + SafeDeleteHandler.invoke(getProject(), new PsiElement[]{psiElement}, true); + } + + @NotNull + @Override + protected String getTestDataPath() { + return PluginPathManager.getPluginHomePath("javaFX") + "/testData/fieldRefactoring/"; + } +} diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/codeInsight/JavaFxGetterSetterPrototypeProvider.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/codeInsight/JavaFxGetterSetterPrototypeProvider.java index 2c3ae170919d..8ed3fd8f0e87 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/codeInsight/JavaFxGetterSetterPrototypeProvider.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/codeInsight/JavaFxGetterSetterPrototypeProvider.java @@ -81,6 +81,28 @@ public class JavaFxGetterSetterPrototypeProvider extends GetterSetterPrototypePr return new PsiMethod[] {setter}; } + @Override + public PsiMethod[] findGetters(PsiClass psiClass, String propertyName) { + final String getterName = suggestGetterName(propertyName); + final PsiMethod specificGetter = psiClass + .findMethodBySignature(JavaPsiFacade.getElementFactory(psiClass.getProject()).createMethod(getterName, PsiType.VOID), false); + if (specificGetter != null) { + final PsiMethod getter = PropertyUtil.findPropertyGetter(psiClass, propertyName, false, false); + return getter == null ? new PsiMethod[] {specificGetter} : new PsiMethod[] {getter, specificGetter}; + } + return super.findGetters(psiClass, propertyName); + } + + @Override + public String suggestGetterName(String propertyName) { + return propertyName + "Property"; + } + + @Override + public boolean isSimpleGetter(PsiMethod method, String oldPropertyName) { + return method.getName().equals(suggestGetterName(oldPropertyName)); + } + @Override public boolean isReadOnly(PsiField field) { return !InheritanceUtil.isInheritor(field.getType(), JavaFxCommonClassNames.JAVAFX_BEANS_VALUE_WRITABLE_VALUE); diff --git a/plugins/javaFX/testData/fieldRefactoring/PropertyDelete.java b/plugins/javaFX/testData/fieldRefactoring/PropertyDelete.java new file mode 100644 index 000000000000..18392348db04 --- /dev/null +++ b/plugins/javaFX/testData/fieldRefactoring/PropertyDelete.java @@ -0,0 +1,18 @@ +import javafx.beans.property.IntegerProperty; +import javafx.beans.property.SimpleIntegerProperty; + +class Test { + private IntegerProperty count = new SimpleIntegerProperty(this, "count"); + + public int getCount() { + return count.get(); + } + + public IntegerProperty countProperty() { + return count; + } + + public void setCount(int count) { + this.count.set(count); + } +} \ No newline at end of file diff --git a/plugins/javaFX/testData/fieldRefactoring/PropertyDelete_after.java b/plugins/javaFX/testData/fieldRefactoring/PropertyDelete_after.java new file mode 100644 index 000000000000..973bbc3a6aff --- /dev/null +++ b/plugins/javaFX/testData/fieldRefactoring/PropertyDelete_after.java @@ -0,0 +1,6 @@ +import javafx.beans.property.IntegerProperty; +import javafx.beans.property.SimpleIntegerProperty; + +class Test { + +} \ No newline at end of file diff --git a/plugins/javaFX/testData/fieldRefactoring/PropertyRename.java b/plugins/javaFX/testData/fieldRefactoring/PropertyRename.java new file mode 100644 index 000000000000..18392348db04 --- /dev/null +++ b/plugins/javaFX/testData/fieldRefactoring/PropertyRename.java @@ -0,0 +1,18 @@ +import javafx.beans.property.IntegerProperty; +import javafx.beans.property.SimpleIntegerProperty; + +class Test { + private IntegerProperty count = new SimpleIntegerProperty(this, "count"); + + public int getCount() { + return count.get(); + } + + public IntegerProperty countProperty() { + return count; + } + + public void setCount(int count) { + this.count.set(count); + } +} \ No newline at end of file diff --git a/plugins/javaFX/testData/fieldRefactoring/PropertyRename_after.java b/plugins/javaFX/testData/fieldRefactoring/PropertyRename_after.java new file mode 100644 index 000000000000..a9ef9cd68a95 --- /dev/null +++ b/plugins/javaFX/testData/fieldRefactoring/PropertyRename_after.java @@ -0,0 +1,18 @@ +import javafx.beans.property.IntegerProperty; +import javafx.beans.property.SimpleIntegerProperty; + +class Test { + private IntegerProperty newName = new SimpleIntegerProperty(this, "count"); + + public int getNewName() { + return newName.get(); + } + + public IntegerProperty newNameProperty() { + return newName; + } + + public void setNewName(int newName) { + this.newName.set(newName); + } +} \ No newline at end of file From 33a7e6cccbf805f3678adea2f8c606301ae29fd2 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Wed, 26 Jun 2013 15:37:41 +0400 Subject: [PATCH 13/30] IDEA-109436 Simplify creation of a gradle project 1. Gradle script template is added; 2. It's possible to specify gradle module type during new project creation now; --- .../newProjectWizard/AddModuleWizard.java | 2 +- .../i18n/ExternalSystemBundle.properties | 2 + .../AbstractExternalSystemSettings.java | 12 ++ .../wizard/AbstractExternalModuleBuilder.java | 180 ++++++++++++++++++ .../wizard/ExternalModuleSettingsStep.java | 58 ++++++ ...bstractExternalProjectSettingsControl.java | 2 +- .../externalSystem/util/PaintAwarePanel.java | 11 +- .../internal/Gradle File.gradle.ft | 12 ++ .../resources/i18n/GradleBundle.properties | 2 +- plugins/gradle/src/META-INF/plugin.xml | 8 +- .../project/wizard/GradleModuleBuilder.java | 73 +++++++ .../wizard}/GradleProjectImportBuilder.java | 3 +- .../wizard}/GradleProjectImportProvider.java | 2 +- .../wizard}/GradleProjectOpenProcessor.java | 2 +- .../GradleProjectSettingsControl.java | 2 +- .../settings/GradleProjectSettings.java | 3 +- .../plugins/gradle/util/GradleUtil.java | 17 +- 17 files changed, 367 insertions(+), 24 deletions(-) create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/AbstractExternalModuleBuilder.java create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/ExternalModuleSettingsStep.java create mode 100644 plugins/gradle/resources/fileTemplates/internal/Gradle File.gradle.ft create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleModuleBuilder.java rename plugins/gradle/src/org/jetbrains/plugins/gradle/service/{settings => project/wizard}/GradleProjectImportBuilder.java (97%) rename plugins/gradle/src/org/jetbrains/plugins/gradle/service/{settings => project/wizard}/GradleProjectImportProvider.java (95%) rename plugins/gradle/src/org/jetbrains/plugins/gradle/service/{settings => project/wizard}/GradleProjectOpenProcessor.java (97%) diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddModuleWizard.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddModuleWizard.java index 167b861e915d..2cb74deb03a5 100644 --- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddModuleWizard.java +++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddModuleWizard.java @@ -89,7 +89,7 @@ public class AddModuleWizard extends AbstractWizard } /** Import mode */ - public AddModuleWizard(Project project, String filePath, ProjectImportProvider... importProviders) { + public AddModuleWizard(@Nullable Project project, String filePath, ProjectImportProvider... importProviders) { super(getImportWizardTitle(project, importProviders), project); myCurrentProject = project; myImportProviders = importProviders; diff --git a/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties b/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties index acd0ee23cdb0..2d08b31b9f08 100644 --- a/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties +++ b/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties @@ -1,5 +1,7 @@ # Import. import.title=Import {0} Projects +module.type.title={0} Module +module.type.description={0} modules are used for developing JVM-based applications with dependencies managed by {0} orphan.modules.text=The modules below are not backed by {0} anymore.
Check those to be removed from the ide project too: # Settings. diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/AbstractExternalSystemSettings.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/AbstractExternalSystemSettings.java index 253cb6d0ceea..9c3e5e7c5776 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/AbstractExternalSystemSettings.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/AbstractExternalSystemSettings.java @@ -74,6 +74,18 @@ public abstract class AbstractExternalSystemSettings extends ModuleBuilder { + + private static final Logger LOG = Logger.getInstance("#" + AbstractExternalModuleBuilder.class.getName()); + + @NotNull private final ExternalSystemSettingsManager mySettingsManager; + @NotNull private final Icon myIcon; + @NotNull private final ProjectSystemId myExternalSystemId; + + @Nullable private final AbstractExternalProjectSettingsControl myExternalProjectSettingsControl; + @Nullable private final String myTemplateConfigName; + + protected AbstractExternalModuleBuilder(@NotNull ProjectSystemId externalSystemId, + @Nullable AbstractExternalProjectSettingsControl control, + @Nullable String templateConfigName) + { + this(ServiceManager.getService(ExternalSystemSettingsManager.class), externalSystemId, control, templateConfigName); + } + + protected AbstractExternalModuleBuilder(@NotNull ExternalSystemSettingsManager manager, + @NotNull ProjectSystemId externalSystemId, + @Nullable AbstractExternalProjectSettingsControl externalProjectSettingsControl, + @Nullable String templateConfigName) + { + mySettingsManager = manager; + myExternalSystemId = externalSystemId; + myTemplateConfigName = templateConfigName; + myExternalProjectSettingsControl = externalProjectSettingsControl; + Icon icon = ExternalSystemUiUtil.getUiAware(externalSystemId).getProjectIcon(); + myIcon = icon == null ? super.getNodeIcon() : icon; + } + + @Override + public String getBuilderId() { + return getClass().getName(); + } + + @Override + public String getPresentableName() { + return ExternalSystemBundle.message("module.type.title", myExternalSystemId.getReadableName()); + } + + @Override + public String getDescription() { + return ExternalSystemBundle.message("module.type.description", myExternalSystemId.getReadableName()); + } + + @Override + public Icon getNodeIcon() { + return myIcon; + } + + @Override + public void setModuleFilePath(@NonNls String path) { + super.setModuleFilePath(path); + String contentPath = getContentEntryPath(); + if (myExternalProjectSettingsControl != null && contentPath != null) { + myExternalProjectSettingsControl.getInitialSettings().setExternalProjectPath(contentPath); + myExternalProjectSettingsControl.reset(); + } + } + + @Override + public ModuleWizardStep[] createWizardSteps(WizardContext wizardContext, ModulesProvider modulesProvider) { + return myExternalProjectSettingsControl == null + ? ModuleWizardStep.EMPTY_ARRAY + : new ModuleWizardStep[]{new ExternalModuleSettingsStep(myExternalProjectSettingsControl)}; + } + + @Override + public void setupRootModel(ModifiableRootModel model) throws ConfigurationException { + String contentPath = getContentEntryPath(); + if (StringUtil.isEmpty(contentPath)) { + return; + } + assert contentPath != null; + File contentRootDir = new File(contentPath); + FileUtilRt.createDirectory(contentRootDir); + LocalFileSystem fileSystem = LocalFileSystem.getInstance(); + VirtualFile vContentRootDir = fileSystem.refreshAndFindFileByIoFile(contentRootDir); + if (vContentRootDir == null) { + return; + } + + model.addContentEntry(vContentRootDir); + model.inheritSdk(); + + + VirtualFile configFile = getExternalProjectConfigFile(vContentRootDir); + if (configFile != null && myTemplateConfigName != null) { + FileTemplateManager manager = FileTemplateManager.getInstance(); + FileTemplate template = manager.getInternalTemplate(myTemplateConfigName); + try { + VfsUtil.saveText(configFile, template.getText()); + } + catch (IOException e) { + LOG.warn(String.format("Unexpected exception on applying template %s config", myExternalSystemId.getReadableName()), e); + throw new ConfigurationException( + e.getMessage(), + String.format("Can't apply %s template config text", myExternalSystemId.getReadableName()) + ); + } + } + + AbstractExternalSystemSettings settings = mySettingsManager.getSettings(model.getProject(), myExternalSystemId); + S externalProjectSettings = createSettings(); + if (myExternalProjectSettingsControl != null) { + String errorMessage = myExternalProjectSettingsControl.apply(externalProjectSettings); + myExternalProjectSettingsControl.disposeUIResources(); + if (errorMessage != null) { + throw new ConfigurationException(errorMessage); + } + } + //noinspection unchecked + settings.linkProject(externalProjectSettings); + } + + @NotNull + protected abstract S createSettings(); + + /** + * Asks external system-specific module builder to prepare external system config file if necessary. + * + * @param contentRootDir new module's content root dir + * @return external system config file created by the external system-specific implementation (if any); + * null as an indication that no external system config file has been created + */ + @Nullable + protected abstract VirtualFile getExternalProjectConfigFile(@NotNull VirtualFile contentRootDir); +} diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/ExternalModuleSettingsStep.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/ExternalModuleSettingsStep.java new file mode 100644 index 000000000000..50020fd9ca09 --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/ExternalModuleSettingsStep.java @@ -0,0 +1,58 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.externalSystem.service.project.wizard; + +import com.intellij.ide.util.projectWizard.ModuleWizardStep; +import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings; +import com.intellij.openapi.externalSystem.util.ExternalSystemSettingsControl; +import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil; +import com.intellij.openapi.externalSystem.util.PaintAwarePanel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +/** + * @author Denis Zhdanov + * @since 6/26/13 1:38 PM + */ +public class ExternalModuleSettingsStep extends ModuleWizardStep { + + @NotNull private final ExternalSystemSettingsControl myControl; + + @Nullable private PaintAwarePanel myComponent; + + public ExternalModuleSettingsStep(@NotNull ExternalSystemSettingsControl control) { + myControl = control; + } + + @Override + public JComponent getComponent() { + PaintAwarePanel result = myComponent; + if (result == null) { + result = new PaintAwarePanel(); + myControl.fillUi(result, 0); + ExternalSystemUiUtil.fillBottom(result); + myComponent = result; + } + + return result; + } + + @Override + public void updateDataModel() { + } +} diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalProjectSettingsControl.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalProjectSettingsControl.java index 0103c69a4b22..acba6f3101df 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalProjectSettingsControl.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalProjectSettingsControl.java @@ -44,7 +44,7 @@ public abstract class AbstractExternalProjectSettingsControl myPaintCallback; - public PaintAwarePanel(LayoutManager layout) { - super(layout); + public PaintAwarePanel() { + this(new GridBagLayout()); } - public PaintAwarePanel() { + public PaintAwarePanel(LayoutManager layout) { + super(layout); } @Override diff --git a/plugins/gradle/resources/fileTemplates/internal/Gradle File.gradle.ft b/plugins/gradle/resources/fileTemplates/internal/Gradle File.gradle.ft new file mode 100644 index 000000000000..072e5e57717b --- /dev/null +++ b/plugins/gradle/resources/fileTemplates/internal/Gradle File.gradle.ft @@ -0,0 +1,12 @@ +apply plugin: 'java' + +sourceCompatibility = 1.5 +version = '1.0' + +repositories { + mavenCentral() +} + +dependencies { + testCompile group: 'junit', name: 'junit', version: '4.11' +} \ No newline at end of file diff --git a/plugins/gradle/resources/i18n/GradleBundle.properties b/plugins/gradle/resources/i18n/GradleBundle.properties index 7c1c845577f8..d5c12d03c11c 100644 --- a/plugins/gradle/resources/i18n/GradleBundle.properties +++ b/plugins/gradle/resources/i18n/GradleBundle.properties @@ -81,7 +81,7 @@ gradle.generic.text.error.jar.not.found=Gradle jars location is unknown gradle.home.setting.type.deduced=Gradle location is deduced gradle.home.setting.type.unknown=Gradle location is unknown gradle.home.setting.type.explicit.correct=Gradle location is defined -gradle.home.setting.type.explicit.incorrect=Gradle location is incorrect +gradle.home.setting.type.explicit.incorrect=Gradle location is incorrect.\nLocation:{0} gradle.toolwindow.text.no.linked.project=\nThere is no linked Gradle project\nYou can {@action Gradle.LinkToProject} one. gradle.toolwindow.linked.action.text=Add diff --git a/plugins/gradle/src/META-INF/plugin.xml b/plugins/gradle/src/META-INF/plugin.xml index 93e3fc526ec1..9bd4ffb786c6 100644 --- a/plugins/gradle/src/META-INF/plugin.xml +++ b/plugins/gradle/src/META-INF/plugin.xml @@ -29,14 +29,16 @@ - - + + + + - + diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleModuleBuilder.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleModuleBuilder.java new file mode 100644 index 000000000000..787a81d8b374 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleModuleBuilder.java @@ -0,0 +1,73 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.gradle.service.project.wizard; + +import com.intellij.openapi.externalSystem.service.project.wizard.AbstractExternalModuleBuilder; +import com.intellij.openapi.module.JavaModuleType; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.module.StdModuleTypes; +import com.intellij.openapi.projectRoots.JavaSdk; +import com.intellij.openapi.projectRoots.SdkTypeId; +import com.intellij.openapi.util.io.FileUtilRt; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.gradle.service.settings.GradleProjectSettingsControl; +import org.jetbrains.plugins.gradle.settings.GradleProjectSettings; +import org.jetbrains.plugins.gradle.util.GradleConstants; + +import java.io.File; + +/** + * @author Denis Zhdanov + * @since 6/26/13 11:10 AM + */ +public class GradleModuleBuilder extends AbstractExternalModuleBuilder { + + public GradleModuleBuilder() { + super(GradleConstants.SYSTEM_ID, new GradleProjectSettingsControl(new GradleProjectSettings()), "Gradle File.gradle"); + } + + @Nullable + @Override + protected VirtualFile getExternalProjectConfigFile(@NotNull VirtualFile contentRootDir) { + File gradleScript = new File(contentRootDir.getPath(), GradleConstants.DEFAULT_SCRIPT_NAME); + FileUtilRt.createIfNotExists(gradleScript); + return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(gradleScript); + } + + @Override + public boolean isSuitableSdkType(SdkTypeId sdk) { + return sdk == JavaSdk.getInstance(); + } + + @Override + public String getGroupName() { + return JavaModuleType.JAVA_GROUP; + } + + @Override + public ModuleType getModuleType() { + return StdModuleTypes.JAVA; + } + + @NotNull + @Override + protected GradleProjectSettings createSettings() { + return new GradleProjectSettings(); + } +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectImportBuilder.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleProjectImportBuilder.java similarity index 97% rename from plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectImportBuilder.java rename to plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleProjectImportBuilder.java index a7bf058a0777..e4a6ff411198 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectImportBuilder.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleProjectImportBuilder.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.gradle.service.settings; +package org.jetbrains.plugins.gradle.service.project.wizard; import com.intellij.externalSystem.JavaProjectData; import com.intellij.ide.util.projectWizard.WizardContext; @@ -32,6 +32,7 @@ import com.intellij.pom.java.LanguageLevel; import icons.GradleIcons; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.gradle.service.settings.ImportFromGradleControl; import org.jetbrains.plugins.gradle.util.GradleBundle; import org.jetbrains.plugins.gradle.util.GradleConstants; diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectImportProvider.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleProjectImportProvider.java similarity index 95% rename from plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectImportProvider.java rename to plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleProjectImportProvider.java index b9db922274e2..8e5246538ec4 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectImportProvider.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleProjectImportProvider.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.gradle.service.settings; +package org.jetbrains.plugins.gradle.service.project.wizard; import com.intellij.openapi.externalSystem.service.project.wizard.AbstractExternalProjectImportProvider; import com.intellij.openapi.vfs.VirtualFile; diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectOpenProcessor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleProjectOpenProcessor.java similarity index 97% rename from plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectOpenProcessor.java rename to plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleProjectOpenProcessor.java index ebbda1ed24c9..03ac43cf75d9 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectOpenProcessor.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleProjectOpenProcessor.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.gradle.service.settings; +package org.jetbrains.plugins.gradle.service.project.wizard; import com.intellij.ide.util.newProjectWizard.AddModuleWizard; import com.intellij.ide.util.projectWizard.WizardContext; diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java index 6319e1a37cd6..cc8eb204e95f 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java @@ -192,7 +192,7 @@ public class GradleProjectSettingsControl extends AbstractExternalProjectSetting else if (!myInstallationManager.isGradleSdkHome(new File(gradleHomePath))) { myGradleHomeSettingType = LocationSettingType.EXPLICIT_INCORRECT; new DelayedBalloonInfo(MessageType.ERROR, myGradleHomeSettingType, 0).run(); - return GradleBundle.message("gradle.home.setting.type.explicit.incorrect"); + return GradleBundle.message("gradle.home.setting.type.explicit.incorrect", gradleHomePath); } } settings.setPreferLocalInstallationToWrapper(myUseLocalDistributionButton.isSelected()); diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleProjectSettings.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleProjectSettings.java index 369f2f9d8d80..a254be804b50 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleProjectSettings.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleProjectSettings.java @@ -25,7 +25,8 @@ import org.jetbrains.annotations.Nullable; */ public class GradleProjectSettings extends ExternalProjectSettings { - @Nullable private String myGradleHome; + @Nullable private String myGradleHome; + private boolean myPreferLocalInstallationToWrapper; @Nullable diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java index 7c3a69d58355..acde80d07bba 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java @@ -58,8 +58,8 @@ public class GradleUtil { /** * Tries to parse what gradle version should be used with gradle wrapper for the gradle project located at the given path. * - * @param gradleProjectPath target gradle project path - * @return gradle version should be used with gradle wrapper for the gradle project located at the given path + * @param gradleProjectPath target gradle project config's (*.gradle) path or config file's directory path. + * @return gradle version should be used with gradle wrapper for the gradle project located at the given path * if any; null otherwise */ @Nullable @@ -68,11 +68,16 @@ public class GradleUtil { return null; } File file = new File(gradleProjectPath); - if (!file.isFile()) { - return null; - } - File gradleDir = new File(file.getParentFile(), "gradle"); + // There is a possible case that given path points to a gradle script (*.gradle) but it's also possible that + // it references script's directory. We want to provide flexibility here. + File gradleDir; + if (file.isFile()) { + gradleDir = new File(file.getParentFile(), "gradle"); + } + else { + gradleDir = file; + } if (!gradleDir.isDirectory()) { return null; } From 1c6686d00fff53b0edf033715f46c61c6f90ab23 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Wed, 26 Jun 2013 15:47:47 +0400 Subject: [PATCH 14/30] IDEA-109617 External system: Detach (minus) button could be added to toolbar near Attach (plus) button --- .../util/ExternalSystemConstants.java | 6 ++-- .../action/DetachExternalProjectAction.java | 30 +++++++++++-------- .../task/ui/ExternalSystemTasksPanel.java | 2 +- .../src/idea/ExternalSystemActions.xml | 1 + 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemConstants.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemConstants.java index f3a606d25054..9e6a7af3b8f8 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemConstants.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemConstants.java @@ -31,11 +31,11 @@ public class ExternalSystemConstants { @NonNls @NotNull public static final String TOOL_WINDOW_TOOLBAR_ACTIONS_GROUP_ID = "ExternalSystem.ToolWindow.Toolbar"; @NonNls @NotNull public static final String TREE_ACTIONS_GROUP_ID = "ExternalSystem.Tree.Context"; - @NonNls @NotNull public static final String TOOL_WINDOW_PLACE = "ExternalSystem.ToolWindow"; - @NonNls @NotNull public static final String TREE_PLACE = "ExternalSystem.Tree"; + @NonNls @NotNull public static final String TOOL_WINDOW_PLACE = "ExternalSystem.ToolWindow"; + @NonNls @NotNull public static final String TREE_CONTEXT_MENU_PLACE = "ExternalSystem.Tree.Context.Menu"; @NotNull public static final String DEBUG_RUNNER_ID = "ExternalSystemTaskDebugRunner"; - @NotNull public static final String RUNNER_ID = "ExternalSystemTaskRunner"; + @NotNull public static final String RUNNER_ID = "ExternalSystemTaskRunner"; public static final boolean VERBOSE_PROCESSING = SystemProperties.getBooleanProperty("external.system.verbose.processing", false); public static final int RECENT_TASKS_NUMBER = SystemProperties.getIntProperty("external.system.recent.tasks.number", 7); diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/DetachExternalProjectAction.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/DetachExternalProjectAction.java index abfa7efaf672..a53d21df02c5 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/DetachExternalProjectAction.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/DetachExternalProjectAction.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.externalSystem.action; +import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DataContext; @@ -30,15 +31,18 @@ import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemTasksTr import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings; import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings; import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings; -import com.intellij.openapi.externalSystem.util.*; +import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; +import com.intellij.openapi.externalSystem.util.ExternalSystemBundle; +import com.intellij.openapi.externalSystem.util.ExternalSystemConstants; +import com.intellij.openapi.externalSystem.util.ExternalSystemUtil; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.SystemInfoRt; import com.intellij.util.containers.ContainerUtilRt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.*; import java.util.Collections; import java.util.List; @@ -51,15 +55,19 @@ public class DetachExternalProjectAction extends AnAction implements DumbAware { public DetachExternalProjectAction() { getTemplatePresentation().setText(ExternalSystemBundle.message("action.detach.external.project.text")); getTemplatePresentation().setDescription(ExternalSystemBundle.message("action.detach.external.project.description")); + getTemplatePresentation().setIcon(SystemInfoRt.isMac ? AllIcons.ToolbarDecorator.Mac.Remove : AllIcons.ToolbarDecorator.Remove); } @Override public void update(AnActionEvent e) { MyInfo info = getProcessingInfo(e.getDataContext()); - if (info.icon != null) { - e.getPresentation().setIcon(info.icon); + String place = e.getPlace(); + if (ExternalSystemConstants.TOOL_WINDOW_PLACE.equals(place)) { + e.getPresentation().setEnabled(info.externalProject != null); + } + else if (ExternalSystemConstants.TREE_CONTEXT_MENU_PLACE.equals(place)) { + e.getPresentation().setVisible(info.externalProject != null); } - e.getPresentation().setVisible(info.externalProject != null); } @Override @@ -126,39 +134,35 @@ public class DetachExternalProjectAction extends AnAction implements DumbAware { AbstractExternalSystemSettings settings = manager.getSettingsProvider().fun(ideProject); ExternalProjectSettings externalProjectSettings = settings.getLinkedProjectSettings(externalProject.getPath()); AbstractExternalSystemLocalSettings localSettings = manager.getLocalSettingsProvider().fun(ideProject); - Icon icon = ExternalSystemUiUtil.getUiAware(externalSystemId).getProjectIcon(); + return new MyInfo(externalProjectSettings == null ? null : settings, localSettings == null ? null : localSettings, externalProjectSettings == null ? null : externalProject, ideProject, - externalSystemId, - icon); + externalSystemId); } private static class MyInfo { - public static final MyInfo EMPTY = new MyInfo(null, null, null, null, null, null); + public static final MyInfo EMPTY = new MyInfo(null, null, null, null, null); @Nullable public final AbstractExternalSystemSettings settings; @Nullable public final AbstractExternalSystemLocalSettings localSettings; @Nullable public final ExternalProjectPojo externalProject; @Nullable public final Project ideProject; @Nullable public final ProjectSystemId externalSystemId; - @Nullable public final Icon icon; MyInfo(@Nullable AbstractExternalSystemSettings settings, @Nullable AbstractExternalSystemLocalSettings localSettings, @Nullable ExternalProjectPojo externalProject, @Nullable Project ideProject, - @Nullable ProjectSystemId externalSystemId, - @Nullable Icon icon) + @Nullable ProjectSystemId externalSystemId) { this.settings = settings; this.localSettings = localSettings; this.externalProject = externalProject; this.ideProject = ideProject; this.externalSystemId = externalSystemId; - this.icon = icon; } } } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksPanel.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksPanel.java index 5e8ae40e4855..c1a068ff9c56 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksPanel.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksPanel.java @@ -99,7 +99,7 @@ public class ExternalSystemTasksPanel extends SimpleToolWindowPanel implements D } }; ExternalSystemUiUtil.apply(settings, myAllTasksModel); - CustomizationUtil.installPopupHandler(myAllTasksTree, TREE_ACTIONS_GROUP_ID, TREE_PLACE); + CustomizationUtil.installPopupHandler(myAllTasksTree, TREE_ACTIONS_GROUP_ID, TREE_CONTEXT_MENU_PLACE); ActionManager actionManager = ActionManager.getInstance(); ActionGroup group = (ActionGroup)actionManager.getAction(TOOL_WINDOW_TOOLBAR_ACTIONS_GROUP_ID); diff --git a/platform/platform-resources/src/idea/ExternalSystemActions.xml b/platform/platform-resources/src/idea/ExternalSystemActions.xml index e99c6ae3d212..c92e52a70f3f 100644 --- a/platform/platform-resources/src/idea/ExternalSystemActions.xml +++ b/platform/platform-resources/src/idea/ExternalSystemActions.xml @@ -14,6 +14,7 @@ + From 2f96118cfb62e7d52cf76ea3a159e399b80bb604 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Wed, 26 Jun 2013 15:51:38 +0400 Subject: [PATCH 15/30] IDEA-109607 Gradle: after project importing project's parent directory is set as linked project name --- .../service/settings/AbstractExternalSystemConfigurable.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalSystemConfigurable.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalSystemConfigurable.java index 90fed07d6a85..a92898b4f4b9 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalSystemConfigurable.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractExternalSystemConfigurable.java @@ -186,9 +186,10 @@ public abstract class AbstractExternalSystemConfigurable< @NotNull protected abstract ExternalSystemSettingsControl createProjectSettingsControl(@NotNull ProjectSettings settings); + @SuppressWarnings("MethodMayBeStatic") @NotNull protected String getProjectName(@NotNull String path) { - return new File(path).getParentFile().getName(); + return new File(path).getName(); } private void prepareSystemSettings(@NotNull SystemSettings s) { From dabd51bfab9a3563f1eed403af01c651a759ef57 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 26 Jun 2013 14:24:17 +0200 Subject: [PATCH 16/30] Tools and View menus contain much disabled actions and groups --- .../actionSystem/CompactActionGroup.java | 24 +++++++ .../DefaultCompactActionGroup.java | 35 ++++++++++ .../actionSystem/impl/ActionManagerImpl.java | 7 +- .../openapi/actionSystem/impl/Utils.java | 67 +++++++++++++++++-- .../src/idea/PlatformActions.xml | 4 +- 5 files changed, 130 insertions(+), 7 deletions(-) create mode 100644 platform/platform-api/src/com/intellij/openapi/actionSystem/CompactActionGroup.java create mode 100644 platform/platform-api/src/com/intellij/openapi/actionSystem/DefaultCompactActionGroup.java diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/CompactActionGroup.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/CompactActionGroup.java new file mode 100644 index 000000000000..b220ae726d2f --- /dev/null +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/CompactActionGroup.java @@ -0,0 +1,24 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.actionSystem; + +/** + * Markup interface to show Action Manager that disabled action shouldn't be shown + * + * @author Konstantin Bulenkov + */ +public interface CompactActionGroup { +} diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/DefaultCompactActionGroup.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/DefaultCompactActionGroup.java new file mode 100644 index 000000000000..e023324ef5fb --- /dev/null +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/DefaultCompactActionGroup.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.actionSystem; + +import org.jetbrains.annotations.NotNull; + +/** + * @author Konstantin Bulenkov + */ +public class DefaultCompactActionGroup extends DefaultActionGroup implements CompactActionGroup { + public DefaultCompactActionGroup() { + super(); + } + + public DefaultCompactActionGroup(@NotNull AnAction... actions) { + super(actions); + } + + public DefaultCompactActionGroup(String shortName, boolean popup) { + super(shortName, popup); + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java index 59e9e3c5acbf..26219ca4be28 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java @@ -98,6 +98,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat @NonNls public static final String DESCRIPTION = "description"; @NonNls public static final String TEXT_ATTR_NAME = "text"; @NonNls public static final String POPUP_ATTR_NAME = "popup"; + @NonNls public static final String COMPACT_ATTR_NAME = "compact"; @NonNls public static final String SEPARATOR_ELEMENT_NAME = "separator"; @NonNls public static final String REFERENCE_ELEMENT_NAME = "reference"; @NonNls public static final String GROUPID_ATTR_NAME = "group-id"; @@ -502,7 +503,11 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat } String className = element.getAttributeValue(CLASS_ATTR_NAME); if (className == null) { // use default group if class isn't specified - className = DefaultActionGroup.class.getName(); + if ("true".equals(element.getAttributeValue(COMPACT_ATTR_NAME))) { + className = DefaultCompactActionGroup.class.getName(); + } else { + className = DefaultActionGroup.class.getName(); + } } try { Class aClass = Class.forName(className, true, loader); diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java index 1fc9f70cd501..0aa39d3f8423 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java @@ -82,8 +82,19 @@ public class Utils{ @NotNull DataContext context, String place, ActionManager actionManager){ - expandActionGroup(group, list, presentationFactory, context, place, actionManager, false); + expandActionGroup(group, list, presentationFactory, context, place, actionManager, false, group instanceof CompactActionGroup); } + + public static void expandActionGroup(@NotNull ActionGroup group, + List list, + PresentationFactory presentationFactory, + DataContext context, + @NotNull String place, + ActionManager actionManager, + boolean transparentOnly) { + expandActionGroup(group, list, presentationFactory, context, place, actionManager, transparentOnly, false); + } + /** * @param list this list contains expanded actions. * @param actionManager manager @@ -94,7 +105,8 @@ public class Utils{ DataContext context, @NotNull String place, ActionManager actionManager, - boolean transparentOnly) { + boolean transparentOnly, + boolean hideDisabled) { Presentation presentation = presentationFactory.getPresentation(group); AnActionEvent e = new AnActionEvent( null, @@ -126,11 +138,15 @@ public class Utils{ if (!doUpdate(child, e1, presentation)) continue; } - if (!presentation.isVisible()) { // don't create invisible items in the menu + if (!presentation.isVisible() || (!presentation.isEnabled() && hideDisabled)) { // don't create invisible items in the menu continue; } if (child instanceof ActionGroup) { ActionGroup actionGroup = (ActionGroup)child; + boolean skip = hideDisabled && !hasEnabledChildren(actionGroup, presentationFactory, context, place); + if (skip) { + continue; + } if (actionGroup.isPopup()) { // popup menu has its own presentation if (actionGroup.disableIfNoVisibleChildren()) { final boolean visibleChildren = hasVisibleChildren(actionGroup, presentationFactory, context, place); @@ -140,10 +156,11 @@ public class Utils{ presentation.setEnabled(actionGroup.canBePerformed(context) || visibleChildren); } + list.add(child); } else { - expandActionGroup((ActionGroup)child, list, presentationFactory, context, place, actionManager); + expandActionGroup((ActionGroup)child, list, presentationFactory, context, place, actionManager, false, hideDisabled); } } else if (child instanceof Separator) { @@ -152,6 +169,9 @@ public class Utils{ } } else { + if (hideDisabled && !hasEnabledChildren(new DefaultActionGroup(child), presentationFactory, context, place)) { + continue; + } list.add(child); } } @@ -219,6 +239,45 @@ public class Utils{ return false; } + private static boolean hasEnabledChildren(ActionGroup group, PresentationFactory factory, DataContext context, String place) { + AnActionEvent event = new AnActionEvent(null, context, place, factory.getPresentation(group), ActionManager.getInstance(), 0); + event.setInjectedContext(group.isInInjectedContext()); + for (AnAction anAction : group.getChildren(event)) { + if (anAction == null) { + LOG.error("Null action found in group " + group + ", " + factory.getPresentation(group)); + continue; + } + if (anAction instanceof Separator) { + continue; + } + final Project project = PlatformDataKeys.PROJECT.getData(context); + if (project != null && DumbService.getInstance(project).isDumb() && !anAction.isDumbAware()) { + continue; + } + + final Presentation presentation = factory.getPresentation(anAction); + updateGroupChild(context, place, anAction, presentation); + if (anAction instanceof ActionGroup) { + ActionGroup childGroup = (ActionGroup)anAction; + + // popup menu must be visible itself + if (childGroup.isPopup()) { + if (!presentation.isEnabled()) { + continue; + } + } + + if (hasEnabledChildren(childGroup, factory, context, place)) { + return true; + } + } + else if (presentation.isEnabled()) { + return true; + } + } + + return false; + } public static void updateGroupChild(DataContext context, String place, AnAction anAction, final Presentation presentation) { AnActionEvent event1 = new AnActionEvent(null, context, place, presentation, ActionManager.getInstance(), 0); diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index 27b890e9f620..8839501c7a03 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -263,7 +263,7 @@ - + @@ -319,7 +319,7 @@ - + From fd778db30c5d4ca85bdeb33decbe57b8d82c0b3d Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Wed, 26 Jun 2013 16:20:04 +0400 Subject: [PATCH 17/30] IDEA-109353 hg4idea plugin shows only first letter of author. *annotation pattern changed for --verbose version instead of --quiet; *LOG error added for incorrect date parsing --- .../hg4idea/command/HgAnnotateCommand.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgAnnotateCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgAnnotateCommand.java index 879c6f0428b0..5a01722023ad 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgAnnotateCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgAnnotateCommand.java @@ -12,6 +12,7 @@ // limitations under the License. package org.zmlx.hg4idea.command; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.history.VcsFileRevision; import org.jetbrains.annotations.NotNull; @@ -21,6 +22,8 @@ import org.zmlx.hg4idea.execution.HgCommandExecutor; import org.zmlx.hg4idea.execution.HgCommandResult; import org.zmlx.hg4idea.provider.annotate.HgAnnotationLine; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -29,8 +32,9 @@ import java.util.regex.Pattern; public class HgAnnotateCommand { + private static final Logger LOG = Logger.getInstance(HgAnnotateCommand.class); private static final Pattern LINE_PATTERN = Pattern.compile( - "\\s*(.+)\\s+([0-9]+)\\s+([0-9a-fA-F]+)\\s+([0-9]{4}-[0-9]{2}-[0-9]{2}):\\s*([0-9]+):\\s(.*)" + "\\s*(.+)\\s+([0-9]+)\\s+([0-9a-fA-F]+)\\s+([a-zA-Z]{3}\\s+[a-zA-Z]{3}\\s+[0-9]{2}\\s+.*[0-9]{4}.+):\\s*([0-9]+):\\s(.*)" ); private static final int USER_GROUP = 1; @@ -48,7 +52,7 @@ public class HgAnnotateCommand { public List execute(@NotNull HgFile hgFile, VcsFileRevision revision) { final List arguments = new ArrayList(); - arguments.add("-cqnudl"); + arguments.add("-cvnudl"); if (revision != null) { arguments.add("-r"); HgRevisionNumber revisionNumber = (HgRevisionNumber)revision.getRevisionNumber(); @@ -72,7 +76,15 @@ public class HgAnnotateCommand { if (matcher.matches()) { String user = matcher.group(USER_GROUP); HgRevisionNumber rev = HgRevisionNumber.getInstance(matcher.group(REVISION_GROUP), matcher.group(CHANGESET_GROUP)); - String date = matcher.group(DATE_GROUP); + String dateGroup = matcher.group(DATE_GROUP); + SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM d HH:mm:ss yyyy Z"); + String date = ""; + try { + date = new SimpleDateFormat("yyyy-MM-dd").format(dateFormat.parse(dateGroup)); + } + catch (ParseException e) { + LOG.error("Couldn't parse annotation date ", e); + } Integer lineNumber = Integer.valueOf(matcher.group(LINE_NUMBER_GROUP)); String content = matcher.group(CONTENT_GROUP); HgAnnotationLine annotationLine = new HgAnnotationLine( From f2b0f497967f5c167f5edc1976b2175e8880b53a Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Wed, 26 Jun 2013 16:26:22 +0400 Subject: [PATCH 18/30] Test for hg annotation with --verbose info (author name and date) added. --- .../provider/annotate/HgAnnotation.java | 2 +- .../test/annotation/HgAnnotationTest.java | 53 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 plugins/hg4idea/testSrc/hg4idea/test/annotation/HgAnnotationTest.java diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/annotate/HgAnnotation.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/annotate/HgAnnotation.java index fafe7ff89e96..a3c79cf7ca32 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/annotate/HgAnnotation.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/annotate/HgAnnotation.java @@ -41,7 +41,7 @@ public class HgAnnotation extends FileAnnotation { private static final Logger LOG = Logger.getInstance(HgAnnotation.class.getName()); - enum FIELD { + public enum FIELD { USER, REVISION, DATE, LINE, CONTENT } diff --git a/plugins/hg4idea/testSrc/hg4idea/test/annotation/HgAnnotationTest.java b/plugins/hg4idea/testSrc/hg4idea/test/annotation/HgAnnotationTest.java new file mode 100644 index 000000000000..b951c6526d68 --- /dev/null +++ b/plugins/hg4idea/testSrc/hg4idea/test/annotation/HgAnnotationTest.java @@ -0,0 +1,53 @@ +package hg4idea.test.annotation; + +import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vfs.VfsUtilCore; +import com.intellij.openapi.vfs.VirtualFile; +import hg4idea.test.HgPlatformTest; +import org.zmlx.hg4idea.HgFile; +import org.zmlx.hg4idea.command.HgAnnotateCommand; +import org.zmlx.hg4idea.provider.annotate.HgAnnotation; +import org.zmlx.hg4idea.provider.annotate.HgAnnotationLine; + +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import static com.intellij.dvcs.test.Executor.cd; +import static com.intellij.dvcs.test.Executor.echo; +import static hg4idea.test.HgExecutor.hg; + +/** + * @author Nadya Zabrodina + */ +public class HgAnnotationTest extends HgPlatformTest { + String firstCreatedFile = "file.txt"; + + @Override + public void setUp() throws Exception { + super.setUp(); + cd(myRepository); + echo(firstCreatedFile, "a\n"); + hg("commit -m modify"); + echo(firstCreatedFile, "b\n"); + hg("commit -m modify1 -u 'a.bacaba@jetbrains.com' "); + echo(firstCreatedFile, "c\n"); + hg("commit -m modify2 -u 'bacaba.a'"); + } + + public void testAnnotationWithVerboseOption() throws VcsException { + final VirtualFile file = myRepository.findFileByRelativePath(firstCreatedFile); + assert file != null; + List users = Arrays.asList("John Doe ", "a.bacaba@jetbrains.com", "bacaba.a"); + final HgFile hgFile = new HgFile(myRepository, VfsUtilCore.virtualToIoFile(file)); + final String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); + List annotationLines = + new HgAnnotateCommand(myProject).execute(hgFile, null); + for (int i = 0; i < annotationLines.size(); ++i) { + HgAnnotationLine line = annotationLines.get(i); + assertEquals(users.get(i), line.get(HgAnnotation.FIELD.USER)); + assertEquals(date, line.get(HgAnnotation.FIELD.DATE)); + } + } +} From 74fd701a70541298e594886874de87cba4090650 Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 25 Jun 2013 13:48:34 +0400 Subject: [PATCH 19/30] extracted common code --- .../ComponentSerializationUtil.java | 30 +++++++++++++++++++ .../com/intellij/facet/impl/FacetUtil.java | 6 ++-- .../xdebugger/impl/XDebuggerUtilImpl.java | 6 ---- .../impl/breakpoints/XBreakpointBase.java | 10 ++----- .../settings/XDebuggerSettingsManager.java | 3 +- 5 files changed, 35 insertions(+), 20 deletions(-) create mode 100644 platform/core-impl/src/com/intellij/openapi/components/ComponentSerializationUtil.java diff --git a/platform/core-impl/src/com/intellij/openapi/components/ComponentSerializationUtil.java b/platform/core-impl/src/com/intellij/openapi/components/ComponentSerializationUtil.java new file mode 100644 index 000000000000..edf85e09bc3b --- /dev/null +++ b/platform/core-impl/src/com/intellij/openapi/components/ComponentSerializationUtil.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.components; + +import com.intellij.util.ReflectionUtil; + +import java.lang.reflect.TypeVariable; + +/** + * @author nik + */ +public class ComponentSerializationUtil { + public static Class getStateClass(final Class aClass) { + TypeVariable> variable = PersistentStateComponent.class.getTypeParameters()[0]; + return ReflectionUtil.getRawType(ReflectionUtil.resolveVariableInHierarchy(variable, aClass)); + } +} diff --git a/platform/lang-impl/src/com/intellij/facet/impl/FacetUtil.java b/platform/lang-impl/src/com/intellij/facet/impl/FacetUtil.java index 9443efc7d165..6a33a55ce3b2 100644 --- a/platform/lang-impl/src/com/intellij/facet/impl/FacetUtil.java +++ b/platform/lang-impl/src/com/intellij/facet/impl/FacetUtil.java @@ -20,11 +20,11 @@ import com.intellij.facet.*; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.WriteAction; +import com.intellij.openapi.components.ComponentSerializationUtil; import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.module.Module; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; -import com.intellij.util.ReflectionUtil; import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters; import com.intellij.util.xmlb.XmlSerializer; import org.jdom.Element; @@ -32,7 +32,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.serialization.facet.JpsFacetSerializer; -import java.lang.reflect.TypeVariable; import java.util.Arrays; /** @@ -80,8 +79,7 @@ public class FacetUtil { throws InvalidDataException { if (config != null) { if (configuration instanceof PersistentStateComponent) { - TypeVariable> variable = PersistentStateComponent.class.getTypeParameters()[0]; - Class stateClass = ReflectionUtil.getRawType(ReflectionUtil.resolveVariableInHierarchy(variable, configuration.getClass())); + Class stateClass = ComponentSerializationUtil.getStateClass(((PersistentStateComponent)configuration).getClass()); ((PersistentStateComponent)configuration).loadState(XmlSerializer.deserialize(config, stateClass)); } else { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java index f48344ca0e41..d85a155334b7 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java @@ -19,7 +19,6 @@ import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.WriteAction; -import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileDocumentManager; @@ -30,7 +29,6 @@ import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.util.Processor; -import com.intellij.util.ReflectionUtil; import com.intellij.xdebugger.XDebuggerManager; import com.intellij.xdebugger.XDebuggerUtil; import com.intellij.xdebugger.XSourcePosition; @@ -192,10 +190,6 @@ public class XDebuggerUtilImpl extends XDebuggerUtil { }; } - public static Class getStateClass(final Class aClass) { - return ReflectionUtil.getRawType(ReflectionUtil.resolveVariableInHierarchy(PersistentStateComponent.class.getTypeParameters()[0], aClass)); - } - @Nullable public static XDebuggerEvaluator getEvaluator(final XSuspendContext suspendContext) { XExecutionStack executionStack = suspendContext.getActiveExecutionStack(); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java index da0725cd6f15..e820785be91a 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java @@ -16,11 +16,9 @@ package com.intellij.xdebugger.impl.breakpoints; import com.intellij.icons.AllIcons; -import com.intellij.idea.ActionsBundle; import com.intellij.openapi.actionSystem.ActionGroup; import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.DefaultActionGroup; -import com.intellij.openapi.actionSystem.Separator; +import com.intellij.openapi.components.ComponentSerializationUtil; import com.intellij.openapi.editor.markup.GutterDraggableObject; import com.intellij.openapi.editor.markup.GutterIconRenderer; import com.intellij.openapi.project.Project; @@ -32,16 +30,12 @@ import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters; import com.intellij.util.xmlb.XmlSerializer; import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XDebuggerBundle; -import com.intellij.xdebugger.XDebuggerManager; import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.breakpoints.*; import com.intellij.xdebugger.impl.DebuggerSupport; import com.intellij.xdebugger.impl.XDebugSessionImpl; import com.intellij.xdebugger.impl.XDebuggerSupport; -import com.intellij.xdebugger.impl.XDebuggerUtilImpl; import com.intellij.xdebugger.impl.actions.EditBreakpointAction; -import com.intellij.xdebugger.impl.actions.ViewBreakpointsAction; -import com.intellij.xdebugger.impl.actions.XDebuggerActions; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -81,7 +75,7 @@ public class XBreakpointBase, P extends XBreakpointP Element element = myState.getPropertiesElement(); if (element != null) { //noinspection unchecked - myProperties.loadState(XmlSerializer.deserialize(element, XDebuggerUtilImpl.getStateClass(myProperties.getClass()))); + myProperties.loadState(XmlSerializer.deserialize(element, ComponentSerializationUtil.getStateClass(myProperties.getClass()))); } } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerSettingsManager.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerSettingsManager.java index 51306f0d13de..b30a4acd9601 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerSettingsManager.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerSettingsManager.java @@ -23,7 +23,6 @@ import com.intellij.util.xmlb.annotations.AbstractCollection; import com.intellij.util.xmlb.annotations.Attribute; import com.intellij.util.xmlb.annotations.Property; import com.intellij.util.xmlb.annotations.Tag; -import com.intellij.xdebugger.impl.XDebuggerUtilImpl; import com.intellij.xdebugger.settings.XDebuggerSettings; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -83,7 +82,7 @@ public class XDebuggerSettingsManager implements PersistentStateComponent void loadState(final XDebuggerSettings settings, final Element settingsElement) { - Class stateClass = XDebuggerUtilImpl.getStateClass(settings.getClass()); + Class stateClass = ComponentSerializationUtil.getStateClass(settings.getClass()); //noinspection unchecked settings.loadState((T)XmlSerializer.deserialize(settingsElement, stateClass)); } From 56255cb8b5575000a26653d8cd51bb0a787708d1 Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 25 Jun 2013 13:53:09 +0400 Subject: [PATCH 20/30] code reused --- .../intellij/openapi/roots/impl/libraries/LibraryImpl.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java index 0d699f7428f6..310932c81834 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java @@ -17,7 +17,7 @@ package com.intellij.openapi.roots.impl.libraries; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.components.ComponentSerializationUtil; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.roots.ModifiableRootModel; @@ -36,7 +36,6 @@ import com.intellij.openapi.vfs.pointers.VirtualFilePointer; import com.intellij.openapi.vfs.pointers.VirtualFilePointerContainer; import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; import com.intellij.util.ArrayUtil; -import com.intellij.util.ReflectionUtil; import com.intellij.util.SmartList; import com.intellij.util.containers.HashMap; import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters; @@ -271,7 +270,7 @@ public class LibraryImpl extends TraceableDisposable implements LibraryEx.Modifi myProperties = myKind.createDefaultProperties(); final Element propertiesElement = element.getChild(PROPERTIES_ELEMENT); if (propertiesElement != null) { - final Class stateClass = ReflectionUtil.getRawType(ReflectionUtil.resolveVariableInHierarchy(PersistentStateComponent.class.getTypeParameters()[0], myProperties.getClass())); + final Class stateClass = ComponentSerializationUtil.getStateClass(myProperties.getClass()); //noinspection unchecked myProperties.loadState(XmlSerializer.deserialize(propertiesElement, stateClass)); } From c416f8e49c6c186385b2707c84e57a31ea004069 Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 26 Jun 2013 12:21:26 +0400 Subject: [PATCH 21/30] common code extracted --- .../roots/ui/configuration/ProjectJdksConfigurable.java | 2 +- .../src/com/intellij/openapi/ui/MasterDetailsComponent.java | 5 +++++ .../maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java | 3 +-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectJdksConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectJdksConfigurable.java index 356eddb1c5ff..d78731b0a3c8 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectJdksConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectJdksConfigurable.java @@ -172,7 +172,7 @@ public class ProjectJdksConfigurable extends MasterDetailsComponent { } }); actions.add(new MyActionGroupWrapper(group)); - actions.add(new MyDeleteAction(forAll(Conditions.alwaysTrue()))); + actions.add(new MyDeleteAction(Conditions.alwaysTrue())); return actions; } diff --git a/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java b/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java index 72acbaee981a..bce394b2c668 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java @@ -28,6 +28,7 @@ import com.intellij.openapi.ui.popup.ListPopupStep; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Conditions; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.*; import com.intellij.ui.navigation.History; @@ -779,6 +780,10 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom protected class MyDeleteAction extends AnAction implements DumbAware { private final Condition myCondition; + public MyDeleteAction() { + this(Conditions.alwaysTrue()); + } + public MyDeleteAction(Condition availableCondition) { super(CommonBundle.message("button.delete"), CommonBundle.message("button.delete"), PlatformIcons.DELETE_ICON); registerCustomShortcutSet(CommonShortcuts.DELETE, myTree); diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java b/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java index 2efff5245482..6c349e007325 100644 --- a/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java +++ b/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java @@ -33,7 +33,6 @@ import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.PopupStep; import com.intellij.openapi.ui.popup.util.BaseListPopupStep; -import com.intellij.openapi.util.Conditions; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.IconUtil; @@ -167,7 +166,7 @@ public class CopyrightProfilesPanel extends MasterDetailsComponent implements Se addProfileNode(copyrightProfile); } }); - result.add(new MyDeleteAction(forAll(Conditions.alwaysTrue()))); + result.add(new MyDeleteAction()); result.add(new AnAction("Copy", "Copy", PlatformIcons.COPY_ICON) { { registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_D, KeyEvent.CTRL_MASK)), myTree); From 5ca0b2999bc8f2d8a3699c752ce125b0919cba31 Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 26 Jun 2013 16:28:50 +0400 Subject: [PATCH 22/30] external build: use memory temp caches by default for standalone build --- .../impl/src/com/intellij/compiler/server/BuildManager.java | 4 ++-- .../src/org/jetbrains/jps/cmdline/BuildRunner.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index f72ceec1b440..110630d3ee0a 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -825,8 +825,8 @@ public class BuildManager implements ApplicationComponent{ cmdLine.addParameter("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=" + debugPort); } - if (Registry.is("compiler.process.use.memory.temp.cache")) { - cmdLine.addParameter("-D"+ GlobalOptions.USE_MEMORY_TEMP_CACHE_OPTION); + if (!Registry.is("compiler.process.use.memory.temp.cache")) { + cmdLine.addParameter("-D"+ GlobalOptions.USE_MEMORY_TEMP_CACHE_OPTION + "=false"); } if (Registry.is("compiler.process.use.external.javac")) { cmdLine.addParameter("-D"+ GlobalOptions.USE_EXTERNAL_JAVAC_OPTION); diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java index a0e2c3428571..7061fc649300 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java @@ -55,7 +55,7 @@ import static org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage public class BuildRunner { private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.cmdline.BuildRunner"); public static final boolean PARALLEL_BUILD_ENABLED = Boolean.parseBoolean(System.getProperty(GlobalOptions.COMPILE_PARALLEL_OPTION, "false")); - private static final boolean STORE_TEMP_CACHES_IN_MEMORY = PARALLEL_BUILD_ENABLED || System.getProperty(GlobalOptions.USE_MEMORY_TEMP_CACHE_OPTION) != null; + private static final boolean STORE_TEMP_CACHES_IN_MEMORY = PARALLEL_BUILD_ENABLED || Boolean.valueOf(System.getProperty(GlobalOptions.USE_MEMORY_TEMP_CACHE_OPTION, "true")); private final JpsModelLoader myModelLoader; private final List myFilePaths; private final Map myBuilderParams; From ed6ab16ac39b71d4abe200237af494e21992aa43 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 26 Jun 2013 14:46:29 +0200 Subject: [PATCH 23/30] java doc --- .../com/intellij/openapi/actionSystem/CompactActionGroup.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/CompactActionGroup.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/CompactActionGroup.java index b220ae726d2f..cf74d8b47597 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/CompactActionGroup.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/CompactActionGroup.java @@ -16,7 +16,7 @@ package com.intellij.openapi.actionSystem; /** - * Markup interface to show Action Manager that disabled action shouldn't be shown + * Markup interface to tell Action Manager that disabled actions shouldn't be shown * * @author Konstantin Bulenkov */ From a540ff047f8a74eb0a09a8dc87c479d54944cc68 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 26 Jun 2013 13:57:18 +0200 Subject: [PATCH 24/30] cache erased parameter types in MethodSignatureBase (maybe IDEA-109409) --- .../psi/util/MethodSignatureBase.java | 9 +++++ .../psi/util/MethodSignatureUtil.java | 38 +++++++++++-------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBase.java b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBase.java index 2dd259d27396..5a5d808d068c 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBase.java +++ b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBase.java @@ -25,6 +25,7 @@ public abstract class MethodSignatureBase implements MethodSignature { private final PsiSubstitutor mySubstitutor; private final PsiType[] myParameterTypes; + private volatile PsiType[] myErasedParameterTypes; protected final PsiTypeParameter[] myTypeParameters; protected MethodSignatureBase(@NotNull PsiSubstitutor substitutor, @NotNull PsiType[] parameterTypes, @NotNull PsiTypeParameter[] typeParameters) { @@ -69,6 +70,14 @@ public abstract class MethodSignatureBase implements MethodSignature { public PsiTypeParameter[] getTypeParameters() { return myTypeParameters; } + + public PsiType[] getErasedParameterTypes() { + PsiType[] result = myErasedParameterTypes; + if (result == null) { + result = myErasedParameterTypes = MethodSignatureUtil.getErasedParameterTypes(this); + } + return result; + } public boolean equals(Object o) { if (this == o) return true; diff --git a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java index f97ff1736c8d..2ce68ad0876a 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java @@ -23,6 +23,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -63,23 +64,30 @@ public class MethodSignatureUtil { @Override public boolean equals(MethodSignature method1, MethodSignature method2) { - if (method1.isConstructor() != method2.isConstructor()) return false; - if (!method1.isConstructor() && !method1.getName().equals(method2.getName())) return false; - final PsiType[] parameterTypes1 = method1.getParameterTypes(); - final PsiType[] parameterTypes2 = method2.getParameterTypes(); - if (parameterTypes1.length != parameterTypes2.length) return false; - - final PsiSubstitutor substitutor1 = method1.getSubstitutor(); - final PsiSubstitutor substitutor2 = method2.getSubstitutor(); - for (int i = 0; i < parameterTypes1.length; i++) { - final PsiType type1 = TypeConversionUtil.erasure(substitutor1.substitute(parameterTypes1[i]), substitutor1); - final PsiType type2 = TypeConversionUtil.erasure(substitutor2.substitute(parameterTypes2[i]), substitutor2); - if (!Comparing.equal(type1, type2)) return false; - } - return true; + return areSignaturesEqualLightweight(method1, method2) && checkErasedParametersEqual(method1, method2); } }; + private static boolean checkErasedParametersEqual(MethodSignature method1, MethodSignature method2) { + PsiType[] erased1 = method1 instanceof MethodSignatureBase + ? ((MethodSignatureBase)method1).getErasedParameterTypes() : getErasedParameterTypes(method1); + PsiType[] erased2 = method2 instanceof MethodSignatureBase + ? ((MethodSignatureBase)method2).getErasedParameterTypes() : getErasedParameterTypes(method2); + return Arrays.equals(erased1, erased2); + } + + public static PsiType[] getErasedParameterTypes(MethodSignature signature) { + PsiType[] parameterTypes = signature.getParameterTypes(); + if (parameterTypes.length == 0) return PsiType.EMPTY_ARRAY; + + PsiSubstitutor substitutor = signature.getSubstitutor(); + PsiType[] erasedTypes = new PsiType[parameterTypes.length]; + for (int i = 0; i < parameterTypes.length; i++) { + erasedTypes[i] = TypeConversionUtil.erasure(substitutor.substitute(parameterTypes[i]), substitutor); + } + return erasedTypes; + } + public static MethodSignature createMethodSignature(@NonNls @NotNull String name, @Nullable PsiParameterList parameterTypes, @Nullable PsiTypeParameterList typeParameterList, @@ -125,7 +133,7 @@ public class MethodSignatureUtil { final MethodSignature superSignature, final PsiSubstitutor unifyingSubstitutor) { if (unifyingSubstitutor == null) return false; - if (!METHOD_PARAMETERS_ERASURE_EQUALITY.equals(subSignature, superSignature)) return false; + if (!checkErasedParametersEqual(subSignature, superSignature)) return false; final PsiType[] subParameterTypes = subSignature.getParameterTypes(); final PsiType[] superParameterTypes = superSignature.getParameterTypes(); From b842211141bb829a9c2829a8fce1430c0ec262fe Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 26 Jun 2013 14:53:49 +0200 Subject: [PATCH 25/30] a test for goto popups --- .../navigation/ChooseByNameTest.groovy | 45 +++++++++++++++++++ .../ide/util/gotoByName/ChooseByNameBase.java | 31 +++++++------ .../DefaultChooseByNameItemProvider.java | 5 ++- 3 files changed, 66 insertions(+), 15 deletions(-) create mode 100644 java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy diff --git a/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy b/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy new file mode 100644 index 000000000000..78d58bc076b3 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy @@ -0,0 +1,45 @@ +package com.intellij.navigation +import com.intellij.ide.util.gotoByName.ChooseByNameModel +import com.intellij.ide.util.gotoByName.ChooseByNamePopup +import com.intellij.ide.util.gotoByName.GotoClassModel2 +import com.intellij.openapi.application.ModalityState +import com.intellij.psi.PsiElement +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase +import com.intellij.util.Consumer +import com.intellij.util.concurrency.Semaphore +/** + * @author peter + */ +class ChooseByNameTest extends LightCodeInsightFixtureTestCase { + + public void "test trivial goto class"() { + def xxClass = myFixture.addClass("class Xxxxx {}") + def fooXxClass = myFixture.addClass("class FooXxxxx {}") + List elements = createPopup(new GotoClassModel2(project), "Xxx") + assert elements[0] == xxClass + assert elements[2] == fooXxClass + } + + private List createPopup(ChooseByNameModel model, String text) { + def popup = ChooseByNamePopup.createPopup(project, model, (PsiElement)null, "") + List elements = ['empty'] + def semaphore = new Semaphore() + semaphore.down() + popup.scheduleCalcElements(text, false, false, ModalityState.NON_MODAL, { set -> + elements = set as List + semaphore.up() + } as Consumer>) + assert semaphore.waitFor(1000) + return elements + } + + @Override + protected boolean runInDispatchThread() { + return false + } + + @Override + protected void invokeTestRunnable(Runnable runnable) throws Exception { + runnable.run() + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java index 763b66d9efea..fbb792e59d90 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java @@ -63,6 +63,7 @@ import com.intellij.usageView.UsageInfo; import com.intellij.usageView.UsageViewBundle; import com.intellij.usages.*; import com.intellij.util.Alarm; +import com.intellij.util.Consumer; import com.intellij.util.Processor; import com.intellij.util.text.Matcher; import com.intellij.util.text.MatcherHolder; @@ -926,9 +927,9 @@ public abstract class ChooseByNameBase { final Runnable request = new Runnable() { @Override public void run() { - final CalcElementsCallback callback = new CalcElementsCallback() { + final Consumer> callback = new Consumer>() { @Override - public void run(@NotNull final Set elements) { + public void consume(Set elements) { synchronized (myRebuildMutex) { ApplicationManager.getApplication().assertIsDispatchThread(); if (checkDisposed()) { @@ -963,10 +964,7 @@ public abstract class ChooseByNameBase { ((MatcherHolder)cellRenderer).setPatternMatcher(matcher); } - CalcElementsThread calcElementsThread = - new CalcElementsThread(text, myCheckBox.isSelected(), callback, modalityState, postRunnable == null); - myCalcElementsThread = calcElementsThread; - ApplicationManager.getApplication().executeOnPooledThread(calcElementsThread); + scheduleCalcElements(text, myCheckBox.isSelected(), postRunnable == null, modalityState, callback); } }; @@ -980,6 +978,16 @@ public abstract class ChooseByNameBase { }, modalityState); } + public void scheduleCalcElements(String text, + boolean checkboxState, + boolean canCancel, + ModalityState modalityState, + Consumer> callback) { + CalcElementsThread calcElementsThread = new CalcElementsThread(text, checkboxState, callback, modalityState, canCancel); + myCalcElementsThread = calcElementsThread; + ApplicationManager.getApplication().executeOnPooledThread(calcElementsThread); + } + private boolean isShowListAfterCompletionKeyStroke() { return myShowListAfterCompletionKeyStroke; } @@ -1395,7 +1403,7 @@ public abstract class ChooseByNameBase { private class CalcElementsThread implements Runnable { private final String myPattern; private boolean myCheckboxState; - private final CalcElementsCallback myCallback; + private final Consumer> myCallback; private final ModalityState myModalityState; private Set myElements = null; @@ -1405,7 +1413,7 @@ public abstract class ChooseByNameBase { CalcElementsThread(String pattern, boolean checkboxState, - CalcElementsCallback callback, + Consumer> callback, @NotNull ModalityState modalityState, boolean canCancel) { myPattern = pattern; @@ -1469,7 +1477,7 @@ public abstract class ChooseByNameBase { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { - myCallback.run(myElements); + myCallback.consume(myElements); } }, myModalityState); } @@ -1503,6 +1511,7 @@ public abstract class ChooseByNameBase { } private void showCard(final String card, final int delay) { + if (ApplicationManager.getApplication().isUnitTestMode()) return; myShowCardAlarm.cancelAllRequests(); myShowCardAlarm.addRequest(new Runnable() { @Override @@ -1544,10 +1553,6 @@ public abstract class ChooseByNameBase { return NameUtil.buildMatcher(pattern, 0, true, true, pattern.toLowerCase().equals(pattern)); } - private interface CalcElementsCallback { - void run(Set elements); - } - private static class HintLabel extends JLabel { private HintLabel(String text) { super(text, RIGHT); diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultChooseByNameItemProvider.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultChooseByNameItemProvider.java index 54854d790ecd..45b0405daf2e 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultChooseByNameItemProvider.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultChooseByNameItemProvider.java @@ -189,7 +189,7 @@ public class DefaultChooseByNameItemProvider implements ChooseByNameItemProvider } @NotNull - public static String getNamePattern(@NotNull ChooseByNameBase base, String pattern) { + private static String getNamePattern(@NotNull ChooseByNameBase base, String pattern) { pattern = base.transformPattern(pattern); ChooseByNameModel model = base.getModel(); @@ -256,7 +256,8 @@ public class DefaultChooseByNameItemProvider implements ChooseByNameItemProvider @NotNull @Override public Pair fun(String s) { - return Pair.create(getNamePattern(base, s), buildPatternMatcher(getNamePattern(base, s), NameUtil.MatchingCaseSensitivity.NONE)); + String namePattern = getNamePattern(base, s); + return Pair.create(namePattern, buildPatternMatcher(namePattern, NameUtil.MatchingCaseSensitivity.NONE)); } }); } From abff128f32ee63ac1c318e80e3b8e23e5341b240 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 26 Jun 2013 14:54:49 +0200 Subject: [PATCH 26/30] IDEA-109490 (Invalid result with "Replace 'StringBuilder' with 'String'" inspection) --- ...ingBufferReplaceableByStringInspection.java | 18 +++++++++++++++--- .../ConstructorArgument.after.java | 8 ++++++++ .../ConstructorArgument.java | 10 ++++++++++ .../ConstructorArgument2.after.java | 8 ++++++++ .../ConstructorArgument2.java | 10 ++++++++++ .../NoConstructorArgument.after.java | 8 ++++++++ .../NoConstructorArgument.java | 11 +++++++++++ ...ringBufferReplaceableWithStringFixTest.java | 3 +++ 8 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/ConstructorArgument.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/ConstructorArgument.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/ConstructorArgument2.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/ConstructorArgument2.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/NoConstructorArgument.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/NoConstructorArgument.java diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java index 337e3305188f..b8656d6f4d78 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java @@ -104,10 +104,22 @@ public class StringBufferReplaceableByStringInspection extends BaseInspection { final StringBuilder stringExpression; if (isAppendCall(initializer)) { stringExpression = buildStringExpression(initializer, new StringBuilder()); + if (stringExpression == null) { + return; + } + } else if (initializer instanceof PsiNewExpression) { + final PsiNewExpression newExpression = (PsiNewExpression)initializer; + final PsiExpressionList argumentList = newExpression.getArgumentList(); + if (argumentList == null) { + return; + } + final PsiExpression[] arguments = argumentList.getExpressions(); + if (arguments.length == 0 || PsiType.INT.equals(arguments[0].getType())) { + stringExpression = new StringBuilder(); + } else { + stringExpression = new StringBuilder(arguments[0].getText()); + } } else { - stringExpression = new StringBuilder(); - } - if (stringExpression == null) { return; } final PsiCodeBlock codeBlock = PsiTreeUtil.getParentOfType(variable, PsiCodeBlock.class); diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/ConstructorArgument.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/ConstructorArgument.after.java new file mode 100644 index 000000000000..f017c513727f --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/ConstructorArgument.after.java @@ -0,0 +1,8 @@ +package com.siyeh.igfixes.style.replace_with_string; + +class ConstructorArgument { + void m() { + + String s = "init-" + "appended"; + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/ConstructorArgument.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/ConstructorArgument.java new file mode 100644 index 000000000000..09a91e528669 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/ConstructorArgument.java @@ -0,0 +1,10 @@ +package com.siyeh.igfixes.style.replace_with_string; + +class ConstructorArgument { + void m() { + final StringBuilder buffer = new StringBuilder("init-"); + buffer.append("appended"); + + String s = buffer.toString(); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/ConstructorArgument2.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/ConstructorArgument2.after.java new file mode 100644 index 000000000000..67ab03a55eb0 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/ConstructorArgument2.after.java @@ -0,0 +1,8 @@ +package com.siyeh.igfixes.style.replace_with_string; + +class ConstructorArgument2 { + void m() { + + String s = "appended"; + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/ConstructorArgument2.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/ConstructorArgument2.java new file mode 100644 index 000000000000..313625eabbad --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/ConstructorArgument2.java @@ -0,0 +1,10 @@ +package com.siyeh.igfixes.style.replace_with_string; + +class ConstructorArgument2 { + void m() { + final StringBuilder buffer = new StringBuilder(100); + buffer.append("appended"); + + String s = buffer.toString(); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/NoConstructorArgument.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/NoConstructorArgument.after.java new file mode 100644 index 000000000000..66a9fb93f6da --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/NoConstructorArgument.after.java @@ -0,0 +1,8 @@ +package com.siyeh.igfixes.style.replace_with_string; + +class NoConstructorArgument { + void m() { + + String s = "appended" + "appended"; + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/NoConstructorArgument.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/NoConstructorArgument.java new file mode 100644 index 000000000000..733521d254fe --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/style/replace_with_string/NoConstructorArgument.java @@ -0,0 +1,11 @@ +package com.siyeh.igfixes.style.replace_with_string; + +class NoConstructorArgument { + void m() { + final StringBuilder buffer = new StringBuilder(); + buffer.append("appended"); + buffer.append("appended"); + + String s = buffer.toString(); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/style/StringBufferReplaceableWithStringFixTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/style/StringBufferReplaceableWithStringFixTest.java index 954df415919c..bf86b3717d04 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/style/StringBufferReplaceableWithStringFixTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/style/StringBufferReplaceableWithStringFixTest.java @@ -26,4 +26,7 @@ public class StringBufferReplaceableWithStringFixTest extends IGQuickFixesTestCa public void testNonString2() { doTest(InspectionGadgetsBundle.message("string.builder.replaceable.by.string.quickfix")); } public void testMarathon() { doTest(InspectionGadgetsBundle.message("string.builder.replaceable.by.string.quickfix")); } public void testArray() { doTest(InspectionGadgetsBundle.message("string.builder.replaceable.by.string.quickfix")); } + public void testConstructorArgument() { doTest(InspectionGadgetsBundle.message("string.builder.replaceable.by.string.quickfix")); } + public void testConstructorArgument2() { doTest(InspectionGadgetsBundle.message("string.builder.replaceable.by.string.quickfix")); } + public void testNoConstructorArgument() { doTest(InspectionGadgetsBundle.message("string.builder.replaceable.by.string.quickfix")); } } From b91e6d78b78a4321351815bdd2951f93a9a0e5cd Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Wed, 26 Jun 2013 17:56:20 +0400 Subject: [PATCH 27/30] IDEA-54114 Maven: for poms from jars the Add As Maven Project action is enabled but doesn't work --- .../jetbrains/idea/maven/utils/actions/MavenActionUtil.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/actions/MavenActionUtil.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/actions/MavenActionUtil.java index 13a347fdfebd..4658fd49b803 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/actions/MavenActionUtil.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/actions/MavenActionUtil.java @@ -82,7 +82,9 @@ public class MavenActionUtil { } public static boolean isMavenProjectFile(VirtualFile file) { - return file != null && !file.isDirectory() && MavenConstants.POM_XML.equals(file.getName()); + return file != null && !file.isDirectory() + && MavenConstants.POM_XML.equals(file.getName()) + && file.isInLocalFileSystem(); } public static List getMavenProjects(DataContext context) { From 9e8b0dd1506beb9a720979a7acedf98fa027de70 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 26 Jun 2013 16:32:17 +0200 Subject: [PATCH 28/30] IDEA-105534 (false positive "redundant call to String.format" when using String.format(Locale, ...)) --- .../RedundantStringFormatCallInspection.java | 30 ++++++++++--------- .../RedundantStringFormatCall.java | 9 ++++-- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/RedundantStringFormatCallInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/RedundantStringFormatCallInspection.java index ca750e750eff..957e987af54a 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/RedundantStringFormatCallInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/RedundantStringFormatCallInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2012 Bas Leijdekkers + * Copyright 2008-2013 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,15 +15,15 @@ */ package com.siyeh.ig.performance; -import com.intellij.psi.*; -import com.intellij.openapi.project.Project; import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; import com.intellij.psi.tree.IElementType; -import com.intellij.util.IncorrectOperationException; +import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.InspectionGadgetsBundle; +import com.siyeh.ig.psiutils.FormatUtils; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -48,8 +48,7 @@ public class RedundantStringFormatCallInspection extends BaseInspection { return new RedundantStringFormatCallFix(); } - private static class RedundantStringFormatCallFix - extends InspectionGadgetsFix { + private static class RedundantStringFormatCallFix extends InspectionGadgetsFix { @Override @NotNull @@ -59,7 +58,7 @@ public class RedundantStringFormatCallInspection extends BaseInspection { } @Override - protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { + protected void doFix(Project project, ProblemDescriptor descriptor) { final PsiElement element = descriptor.getPsiElement(); final PsiElement parent = element.getParent(); final PsiElement grandParent = parent.getParent(); @@ -108,11 +107,13 @@ public class RedundantStringFormatCallInspection extends BaseInspection { } final PsiExpression firstArgument = arguments[0]; final PsiType firstType = firstArgument.getType(); - if (firstType == null || containsPercentN(firstArgument)) { + if (firstType == null) { return; } - if (firstType.equalsToText(CommonClassNames.JAVA_LANG_STRING) && arguments.length == 1) { - registerMethodCallError(expression); + if (firstType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) { + if (arguments.length == 1 && !containsPercentN(firstArgument)) { + registerMethodCallError(expression); + } } else if (firstType.equalsToText("java.util.Locale")) { if (arguments.length != 2) { @@ -120,12 +121,13 @@ public class RedundantStringFormatCallInspection extends BaseInspection { } final PsiExpression secondArgument = arguments[1]; final PsiType secondType = secondArgument.getType(); - if (secondType == null) { + if (secondType == null || !secondType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) { return; } - if (secondType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) { - registerMethodCallError(expression); + if (containsPercentN(secondArgument)) { + return; } + registerMethodCallError(expression); } } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/redundant_string_format_call/RedundantStringFormatCall.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/redundant_string_format_call/RedundantStringFormatCall.java index 8737fa9fd239..9591444bc4c6 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/redundant_string_format_call/RedundantStringFormatCall.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/redundant_string_format_call/RedundantStringFormatCall.java @@ -1,9 +1,9 @@ package com.siyeh.igtest.performance.redundant_string_format_call; +import java.util.Locale; + import static java.lang.String.format; - - public class RedundantStringFormatCall { public static final String A = String.format("%n"); @@ -12,4 +12,9 @@ public class RedundantStringFormatCall { "asdf%n"); String d = String.format("asdf" + "asdf" + "asdf%n"); String e = format("test"); + + void m() { + System.out.println(String.format("string contains %%n%n")); // ok + System.out.println(String.format(Locale.ENGLISH, "string contains %%n%n")); + } } \ No newline at end of file From 93d991ece53cc5143b3652409efb8e0df0d10553 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 26 Jun 2013 16:34:43 +0200 Subject: [PATCH 29/30] fix quickfix property texts --- .../src/com/siyeh/InspectionGadgetsBundle.properties | 4 +++- .../StringConcatenationArgumentToLogCallInspection.java | 3 +-- .../logging/StringConcatenationArgumentToLogCallFixTest.java | 5 +++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties index b5edf386583a..c0c92f93942b 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties @@ -1853,7 +1853,8 @@ simplifiable.annotation.quickfix=Simplify annotation overloaded.methods.with.same.number.parameters.option=Ignore overloaded methods whose parameter types are definitely incompatible string.concatenation.in.format.call.display.name=String concatenation as argument to 'format()' call string.concatenation.in.format.call.problem.descriptor=#ref() call has a String concatenation argument #loc -string.concatenation.in.format.call.quickfix=Replace concatenation with parameterized log message +string.concatenation.in.format.call.quickfix=Replace concatenation with separate argument +string.concatenation.in.format.call.plural.quickfix=Replace concatenation with separate arguments string.concatenation.in.message.format.call.display.name=String concatenation as argument to 'MessageFormat.format()' call string.concatenation.in.message.format.call.problem.descriptor=String concatenation as argument to 'MessageFormat.format()' call #loc shift.out.of.range.quickfix=Replace ''{0}'' with ''{1}'' @@ -2018,6 +2019,7 @@ arrays.as.list.with.zero.arguments.quickfix=Replace with call to 'Collections.em ignore.classes.extending.throwable.option=Ignore classes extending 'Throwable' string.concatenation.argument.to.log.call.display.name=Non-constant string concatenation as argument to logging call string.concatenation.argument.to.log.call.problem.descriptor=Non-constant string concatenation as argument to #ref() logging call #loc +string.concatenation.argument.to.log.call.quickfix=Replace concatenation with parameterized log message placeholder.count.matches.argument.count.display.name=Number of placeholders does not match number of arguments in logging call placeholder.count.matches.argument.count.more.problem.descriptor=#ref() call has more arguments ({0}) than placeholders ({1}) #loc placeholder.count.matches.argument.count.fewer.problem.descriptor=#ref() call has fewer arguments ({0}) than placeholders ({1}) #loc diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/logging/StringConcatenationArgumentToLogCallInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/logging/StringConcatenationArgumentToLogCallInspection.java index 4c96475dd177..51693929f819 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/logging/StringConcatenationArgumentToLogCallInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/logging/StringConcatenationArgumentToLogCallInspection.java @@ -76,13 +76,12 @@ public class StringConcatenationArgumentToLogCallInspection extends BaseInspecti private static class StringConcatenationArgumentToLogCallFix extends InspectionGadgetsFix { - public StringConcatenationArgumentToLogCallFix() {} @NotNull @Override public String getName() { - return InspectionGadgetsBundle.message("string.concatenation.in.format.call.quickfix"); + return InspectionGadgetsBundle.message("string.concatenation.argument.to.log.call.quickfix"); } @Override diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/logging/StringConcatenationArgumentToLogCallFixTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/logging/StringConcatenationArgumentToLogCallFixTest.java index 9257d3e29062..9d9e56ed346d 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/logging/StringConcatenationArgumentToLogCallFixTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/logging/StringConcatenationArgumentToLogCallFixTest.java @@ -21,11 +21,12 @@ import com.siyeh.ig.IGQuickFixesTestCase; import com.siyeh.ig.logging.StringConcatenationArgumentToLogCallInspection; public class StringConcatenationArgumentToLogCallFixTest extends IGQuickFixesTestCase { + @Override public void setUp() throws Exception { super.setUp(); - myDefaultHint = InspectionGadgetsBundle.message("string.concatenation.in.format.call.quickfix"); - myFixture.addClass("package org.slf4j; public interface Logger { void info(String format); }"); + myDefaultHint = InspectionGadgetsBundle.message("string.concatenation.argument.to.log.call.quickfix"); + myFixture.addClass("package org.slf4j; public interface Logger { void info(String format); }"); myFixture.addClass("package org.slf4j; public class LoggerFactory { public static Logger getLogger(Class clazz) { return null; }}"); myFixture.enableInspections(new StringConcatenationArgumentToLogCallInspection()); } From 45959b751cfd29b948b53e013ec8c2afb6a92c84 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 26 Jun 2013 16:15:13 +0200 Subject: [PATCH 30/30] don't leak choose by name popup in tests --- .../com/intellij/navigation/ChooseByNameTest.groovy | 3 +++ .../intellij/ide/util/gotoByName/ChooseByNamePopup.java | 7 ++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy b/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy index 78d58bc076b3..4a88a81e426c 100644 --- a/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy +++ b/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy @@ -2,7 +2,9 @@ package com.intellij.navigation import com.intellij.ide.util.gotoByName.ChooseByNameModel import com.intellij.ide.util.gotoByName.ChooseByNamePopup import com.intellij.ide.util.gotoByName.GotoClassModel2 +import com.intellij.openapi.Disposable import com.intellij.openapi.application.ModalityState +import com.intellij.openapi.util.Disposer import com.intellij.psi.PsiElement import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase import com.intellij.util.Consumer @@ -22,6 +24,7 @@ class ChooseByNameTest extends LightCodeInsightFixtureTestCase { private List createPopup(ChooseByNameModel model, String text) { def popup = ChooseByNamePopup.createPopup(project, model, (PsiElement)null, "") + Disposer.register(testRootDisposable, { popup.close(false) } as Disposable) List elements = ['empty'] def semaphore = new Semaphore() semaphore.down() diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java index b88af0dde5fc..aa5302ca4b1c 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java @@ -18,6 +18,7 @@ package com.intellij.ide.util.gotoByName; import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.ide.ui.UISettings; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.project.Project; @@ -255,14 +256,10 @@ public class ChooseByNamePopup extends ChooseByNameBase implements ChooseByNameP } cleanupUI(isOk); + if (ApplicationManager.getApplication().isUnitTestMode()) return; myActionListener.onClose(); } - @Nullable - public static ChooseByNamePopup getActivePopup(@NotNull final Project project) { - return CHOOSE_BY_NAME_POPUP_IN_PROJECT_KEY.get(project); - } - private void cleanupUI(boolean ok) { if (myTextPopup != null) { if (ok) {