diff --git a/build/groovy/org/jetbrains/intellij/build/LinuxDistributionCustomizer.groovy b/build/groovy/org/jetbrains/intellij/build/LinuxDistributionCustomizer.groovy index 37dcd5fc0c81..c8fdb2b44a56 100644 --- a/build/groovy/org/jetbrains/intellij/build/LinuxDistributionCustomizer.groovy +++ b/build/groovy/org/jetbrains/intellij/build/LinuxDistributionCustomizer.groovy @@ -34,5 +34,9 @@ abstract class LinuxDistributionCustomizer { */ abstract String rootDirectoryName(String buildNumber) + /** + * Override this method to copy additional files to Linux distribution of the product. + * @param targetDirectory contents of this directory will be packed into .tar.gz archive under {@link #rootDirectoryName(java.lang.String)} + */ void copyAdditionalFiles(BuildContext context, String targetDirectory) {} } diff --git a/build/groovy/org/jetbrains/intellij/build/MacDistributionCustomizer.groovy b/build/groovy/org/jetbrains/intellij/build/MacDistributionCustomizer.groovy index 92af4d0350e5..fea25a526f62 100644 --- a/build/groovy/org/jetbrains/intellij/build/MacDistributionCustomizer.groovy +++ b/build/groovy/org/jetbrains/intellij/build/MacDistributionCustomizer.groovy @@ -19,12 +19,24 @@ package org.jetbrains.intellij.build * @author nik */ abstract class MacDistributionCustomizer { + /** + * Path to icns file containing 32x32 product icon for Mac OS distribution + */ String icnsPath + + /** + * The minimum version of Mac OS where the product is allowed to be installed + */ String minOSXVersion = "10.8" String helpId = "" String docTypes = null List urlSchemes = [] List architectures = ["x86_64"] + + /** + * If {@code true} YourKit agent will be automatically attached when an EAP build of the product starts under Mac OS. This property is + * taken into account only if {@link ProductProperties#enableYourkitAgentInEAP} is {@code true}. + */ boolean enableYourkitAgentInEAP = true /** diff --git a/build/groovy/org/jetbrains/intellij/build/ProductProperties.groovy b/build/groovy/org/jetbrains/intellij/build/ProductProperties.groovy index f0ce127c24b2..a15fb138f608 100644 --- a/build/groovy/org/jetbrains/intellij/build/ProductProperties.groovy +++ b/build/groovy/org/jetbrains/intellij/build/ProductProperties.groovy @@ -106,6 +106,10 @@ public abstract class ProductProperties { * directories of Windows, Linux and Mac OS distributions. If {@code null} no agent files will be bundled. */ String yourkitAgentBinariesDirectoryPath = null + + /** + * If {@code true} YourKit agent will be automatically attached when an EAP build of the product starts. It makes sense only if {@link #yourkitAgentBinariesDirectoryPath} is non-null. + */ boolean enableYourkitAgentInEAP = false List excludedPlugins = [] diff --git a/build/groovy/org/jetbrains/intellij/build/WindowsDistributionCustomizer.groovy b/build/groovy/org/jetbrains/intellij/build/WindowsDistributionCustomizer.groovy index c814d2d2601d..ef315aaa7dfa 100644 --- a/build/groovy/org/jetbrains/intellij/build/WindowsDistributionCustomizer.groovy +++ b/build/groovy/org/jetbrains/intellij/build/WindowsDistributionCustomizer.groovy @@ -54,6 +54,11 @@ abstract class WindowsDistributionCustomizer { */ abstract String rootDirectoryName(String buildNumber) + /** + * Override this method to copy additional files to Windows distribution of the product. + * @param targetDirectory contents of this directory will be packed into zip archive and exe installer, so when the product is installed + * it'll be placed under its root directory. + */ void copyAdditionalFiles(BuildContext context, String targetDirectory) {} String uninstallFeedbackPageUrl(ApplicationInfoProperties applicationInfo) { diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant index 92f9bb3448a6..6f154c16a638 100644 --- a/build/scripts/utils.gant +++ b/build/scripts/utils.gant @@ -876,16 +876,14 @@ binding.setVariable("signExecutableFiles", { String binDir -> }) binding.setVariable("bundledJDKs"){ - bundledJDK(false, paths.sandbox) + bundledJDK(false) } binding.setVariable("bundledJDK64s"){ - bundledJDK(true, paths.sandbox) + bundledJDK(true) } -binding.setVariable("prepareBundledJDKs", { String targetDir -> bundledJDK(false, targetDir)}) - -private bundledJDK(boolean win64, String targetDir) { +private bundledJDK(boolean win64) { requireProperty("artifact.linux.no.jdk", "true") requireProperty("artifact.mac.no.jdk", "true") requireProperty("jdk.oracle.win", "jdk8u") @@ -897,11 +895,11 @@ private bundledJDK(boolean win64, String targetDir) { def jdkDir = new File("${home}/build/jdk/win") if (p("jdk.oracle.win") != "false" && (jdkDir.exists() && jdkDir.isDirectory())) { setProperty("winJDK", getPathToBundledJDK(jdkDir, p("jdk.oracle.win"), (win64 ? "x64.tar.gz": "x86.tar.gz"))) - extractRedistJre(winJDK, "$targetDir/jdk.oracle.win/jre") + extractRedistJre(winJDK, "${paths.sandbox}/jdk.oracle.win/jre") } if (p("jdk.win") != "false" && (jdkDir.exists() && jdkDir.isDirectory())) { setProperty("winCustomJDKx32", getPathToBundledJDK(jdkDir, p("jdk.win"), (win64 ? "x64.tar.gz": "x86.tar.gz"))) - extractRedistJre(winCustomJDKx32, "$targetDir/jdk.win/jre") + extractRedistJre(winCustomJDKx32, "${paths.sandbox}/jdk.win/jre") } jdkDir = new File("${home}/build/jdk/mac") if (p("jdk.mac") != "false" && (jdkDir.exists() && jdkDir.isDirectory())) { @@ -910,7 +908,7 @@ private bundledJDK(boolean win64, String targetDir) { jdkDir = new File("${home}/build/jdk/linux") if (p("jdk.linux") != "false" && (jdkDir.exists() && jdkDir.isDirectory())) { setProperty("linuxJDK", getPathToBundledJDK(jdkDir, p("jdk.linux"), ".tar.gz")) - extractRedistJre(linuxJDK, "$targetDir/jdk.linux/jre") + extractRedistJre(linuxJDK, "${paths.sandbox}/jdk.linux/jre") } } } diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java index 3d80600dd0bb..9ae03ce3cef9 100644 --- a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java +++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java @@ -167,7 +167,15 @@ public class UnusedDeclarationPresentation extends DefaultInspectionToolPresenta @Override public QuickFixAction[] getQuickFixes(@NotNull final RefEntity[] refElements, CommonProblemDescriptor[] allowedDescriptors) { - return myQuickFixActions; + boolean showFixes = false; + for (RefEntity element : refElements) { + if (!getIgnoredRefElements().contains(element) && element.isValid()) { + showFixes = true; + break; + } + } + + return showFixes ? myQuickFixActions : QuickFixAction.EMPTY; } final QuickFixAction[] myQuickFixActions; diff --git a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt index a191aef4b218..9b3a803ea398 100644 --- a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt +++ b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt @@ -223,7 +223,14 @@ open class StateStorageManagerImpl(private val rootTagName: String, throw IllegalArgumentException("Extension is missing for storage file: $filePath") } - val effectiveRoamingType = if (roamingType == RoamingType.DEFAULT && collapsedPath == StoragePathMacros.WORKSPACE_FILE) RoamingType.DISABLED else roamingType + val effectiveRoamingType: RoamingType + if (roamingType != RoamingType.DISABLED && (collapsedPath == StoragePathMacros.WORKSPACE_FILE || collapsedPath == "other.xml")) { + effectiveRoamingType = RoamingType.DISABLED + } + else { + effectiveRoamingType = roamingType + } + val storage = createFileBasedStorage(filePath, collapsedPath, effectiveRoamingType) if (isUseVfsListener == ThreeState.YES && storage is StorageVirtualFileTracker.TrackedStorage) { virtualFileTracker?.put(filePath, storage) diff --git a/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java b/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java index ebe812819b61..2868e00897b8 100644 --- a/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java +++ b/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java @@ -663,6 +663,15 @@ public class VfsUtilCore { return components; } + public static boolean hasInvalidFiles(@NotNull Iterable files) { + for (VirtualFile file : files) { + if (!file.isValid()) { + return true; + } + } + return false; + } + /** * this collection will keep only distinct files/folders, e.g. C:\foo\bar will be removed when C:\foo is added */ diff --git a/platform/indexing-impl/src/com/intellij/util/indexing/AdditionalIndexableFileSet.java b/platform/indexing-impl/src/com/intellij/util/indexing/AdditionalIndexableFileSet.java index f08d23cf143e..e2adf3250ced 100644 --- a/platform/indexing-impl/src/com/intellij/util/indexing/AdditionalIndexableFileSet.java +++ b/platform/indexing-impl/src/com/intellij/util/indexing/AdditionalIndexableFileSet.java @@ -55,7 +55,7 @@ public class AdditionalIndexableFileSet implements IndexableFileSet { private Set getDirectories() { Set directories = cachedDirectories; - if (directories == null || filesInvalidated(directories) || filesInvalidated(cachedFiles)) { + if (directories == null || VfsUtilCore.hasInvalidFiles(directories) || VfsUtilCore.hasInvalidFiles(cachedFiles)) { directories = collectFilesAndDirectories(); } return directories; @@ -83,15 +83,6 @@ public class AdditionalIndexableFileSet implements IndexableFileSet { return directories; } - public static boolean filesInvalidated(Set files) { - for (VirtualFile file : files) { - if (!file.isValid()) { - return true; - } - } - return false; - } - @Override public boolean isInSet(@NotNull VirtualFile file) { return VfsUtilCore.isUnder(file, getDirectories()) || cachedFiles.contains(file); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemPreviewEditorPresentation.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemPreviewEditorPresentation.java index 62693a2c477a..fba7c51962cc 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemPreviewEditorPresentation.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemPreviewEditorPresentation.java @@ -19,7 +19,6 @@ import com.intellij.codeInspection.CommonProblemDescriptor; import com.intellij.codeInspection.ProblemDescriptorBase; import com.intellij.diff.tools.util.FoldingModelSupport; import com.intellij.diff.util.DiffDrawUtil; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.FoldRegion; import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.editor.ex.DocumentEx; @@ -39,19 +38,10 @@ import java.util.stream.Collectors; */ public class ProblemPreviewEditorPresentation { private final static int VIEW_ADDITIONAL_OFFSET = 4; - private final static Logger LOG = Logger.getInstance(ProblemPreviewEditorPresentation.class); private final EditorEx myEditor; private final InspectionResultsView myView; - private final SortedSet myFoldedRegions = new TreeSet<>(new Comparator() { - @Override - public int compare(PreviewEditorFoldingRegion r1, PreviewEditorFoldingRegion r2) { - if (r1 == r2) return 0; - final int diff = r1.startLine - r2.startLine; - LOG.assertTrue(diff != 0); - return diff; - } - }); + private final SortedSet myFoldedRegions = new TreeSet<>(Comparator.comparing(x -> x.startLine)); private final DocumentEx myDocument; public ProblemPreviewEditorPresentation(EditorEx editor, InspectionResultsView view) { diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java index d534377431b2..68a0d15c9479 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java @@ -122,7 +122,7 @@ public class RefElementNode extends SuppressableInspectionTreeNode { @Override public int getProblemCount(boolean allowSuppressed) { - return isLeaf() ? myPresentation.getIgnoredRefElements().contains(getElement()) ? 0 : 1 : super.getProblemCount(allowSuppressed); + return isLeaf() ? myPresentation.getIgnoredRefElements().contains(getElement()) && !(allowSuppressed && isAlreadySuppressedFromView() && isValid()) ? 0 : 1 : super.getProblemCount(allowSuppressed); } @Override diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/suppress/SuppressActionSequentialTask.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/suppress/SuppressActionSequentialTask.java index 24b20e1b0289..7025422712d4 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/suppress/SuppressActionSequentialTask.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/suppress/SuppressActionSequentialTask.java @@ -21,6 +21,7 @@ import com.intellij.codeInspection.ex.InspectionManagerEx; import com.intellij.codeInspection.ex.InspectionToolWrapper; import com.intellij.codeInspection.reference.RefElement; import com.intellij.codeInspection.reference.RefEntity; +import com.intellij.codeInspection.ui.ProblemDescriptionNode; import com.intellij.codeInspection.ui.SuppressableInspectionTreeNode; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; @@ -38,6 +39,7 @@ import com.intellij.util.containers.Queue; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collections; import java.util.List; import java.util.Set; @@ -137,16 +139,19 @@ public class SuppressActionSequentialTask implements SequentialTask { } final RefElement containerRef = refEntity.getRefManager().getReference(container); + final Set suppressedNodes = myContext.getView().getSuppressedNodes(wrapper.getShortName()); if (containerRef != null) { Queue toIgnoreInView = new Queue(1); toIgnoreInView.addLast(containerRef); while (!toIgnoreInView.isEmpty()) { final RefEntity entity = toIgnoreInView.pullFirst(); - final CommonProblemDescriptor[] descriptors = myContext.getPresentation(wrapper).getIgnoredElements().get(entity); - if (descriptors != null) { - for (CommonProblemDescriptor problemDescriptor : descriptors) { - myContext.getView().getSuppressedNodes(wrapper.getShortName()).add(problemDescriptor); + if (node instanceof ProblemDescriptionNode) { + final CommonProblemDescriptor[] descriptors = myContext.getPresentation(wrapper).getIgnoredElements().get(entity); + if (descriptors != null) { + Collections.addAll(suppressedNodes, descriptors); } + } else { + suppressedNodes.add(entity); } final List children = entity.getChildren(); if (children != null) { @@ -156,7 +161,9 @@ public class SuppressActionSequentialTask implements SequentialTask { } } } - myContext.getView().getSuppressedNodes(wrapper.getShortName()).add(descriptor); + if (node instanceof ProblemDescriptionNode) { + suppressedNodes.add(descriptor); + } } catch (IncorrectOperationException e1) { LOG.error(e1); diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchFileServiceImpl.java b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchFileServiceImpl.java index 8f990bcc2237..68ca22e30bca 100644 --- a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchFileServiceImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchFileServiceImpl.java @@ -22,6 +22,7 @@ import com.intellij.lang.LanguageUtil; import com.intellij.lang.PerFileMappings; import com.intellij.lang.PerFileMappingsBase; import com.intellij.openapi.application.AccessToken; +import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.components.PersistentStateComponent; @@ -44,14 +45,14 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileWithId; import com.intellij.psi.LanguageSubstitutor; import com.intellij.psi.LanguageSubstitutors; import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiUtilCore; -import com.intellij.util.PairConsumer; import com.intellij.util.PathUtil; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.indexing.IndexableSetContributor; +import com.intellij.util.indexing.LightDirectoryIndex; import com.intellij.util.messages.MessageBus; import org.jdom.Element; import org.jetbrains.annotations.NotNull; @@ -59,9 +60,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.io.IOException; -import java.util.Collection; -import java.util.List; -import java.util.Set; +import java.util.*; @State(name = "ScratchFileService", storages = @Storage("scratches.xml")) @@ -72,22 +71,14 @@ public class ScratchFileServiceImpl extends ScratchFileService implements Persis private final LightDirectoryIndex myIndex; private final MyLanguages myScratchMapping = new MyLanguages(); - protected ScratchFileServiceImpl(MessageBus messageBus) { - myIndex = new LightDirectoryIndex(messageBus.connect(), NULL_TYPE) { - - @Override - protected void collectRoots(@NotNull PairConsumer consumer) { - LocalFileSystem fileSystem = LocalFileSystem.getInstance(); - for (RootType r : RootType.getAllRootIds()) { - String root = getRootPath(r); - VirtualFile rootFile = fileSystem.findFileByPath(root); - if (rootFile != null) { - consumer.consume(rootFile, r); - } - } + protected ScratchFileServiceImpl(Application application) { + myIndex = new LightDirectoryIndex(application, NULL_TYPE, index -> { + LocalFileSystem fileSystem = LocalFileSystem.getInstance(); + for (RootType r : RootType.getAllRootIds()) { + index.putInfo(fileSystem.findFileByPath(getRootPath(r)), r); } - }; - initFileOpenedListener(messageBus); + }); + initFileOpenedListener(application.getMessageBus()); } @NotNull @@ -101,7 +92,6 @@ public class ScratchFileServiceImpl extends ScratchFileService implements Persis public RootType getRootType(@Nullable VirtualFile file) { if (file == null) return null; VirtualFile directory = file.isDirectory() ? file : file.getParent(); - if (!(directory instanceof VirtualFileWithId)) return null; RootType result = myIndex.getInfoForFile(directory); return result == NULL_TYPE ? null : result; } @@ -314,4 +304,26 @@ public class ScratchFileServiceImpl extends ScratchFileService implements Persis private static Language getLanguageByFileName(@Nullable VirtualFile file) { return file == null ? null : LanguageUtil.getFileTypeLanguage(FileTypeManager.getInstance().getFileTypeByFileName(file.getName())); } + + public static class IndexSetContributor extends IndexableSetContributor { + + @NotNull + @Override + public Set getAdditionalRootsToIndex() { + ScratchFileService instance = ScratchFileService.getInstance(); + LocalFileSystem fileSystem = LocalFileSystem.getInstance(); + HashSet result = ContainerUtil.newHashSet(); + for (RootType rootType : RootType.getAllRootIds()) { + if (rootType.isHidden()) continue; + ContainerUtil.addIfNotNull(result, fileSystem.findFileByPath(instance.getRootPath(rootType))); + } + return result; + } + + @NotNull + @Override + public Set getAdditionalProjectRootsToIndex(@NotNull Project project) { + return Collections.emptySet(); + } + } } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHelper.java b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHelper.java index ccfbe6ccce4b..e2937666a4a4 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHelper.java +++ b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHelper.java @@ -42,6 +42,7 @@ import com.intellij.refactoring.RefactoringBundle; import com.intellij.ui.ReplacePromptDialog; import com.intellij.util.Consumer; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -49,7 +50,7 @@ import java.util.*; * @author Dennis.Ushakov */ public class ExtractMethodHelper { - public static void processDuplicates(@NotNull final PsiElement callElement, + public static void processDuplicates(@Nullable final PsiElement callElement, @NotNull final PsiElement generatedMethod, @NotNull final List scope, @NotNull final SimpleDuplicatesFinder finder, @@ -60,7 +61,7 @@ public class ExtractMethodHelper { replaceDuplicates(callElement, editor, replacer, finder.findDuplicates(scope, generatedMethod)); return; } - final Project project = callElement.getProject(); + final Project project = generatedMethod.getProject(); ProgressManager.getInstance().run(new Task.Backgroundable(project, RefactoringBundle.message("searching.for.duplicates"), true) { public void run(@NotNull ProgressIndicator indicator) { if (myProject == null || myProject.isDisposed()) return; @@ -115,7 +116,7 @@ public class ExtractMethodHelper { * @param duplicates discovered duplicates of extracted code fragment * @see #collectDuplicates(SimpleDuplicatesFinder, List, PsiElement) */ - public static void replaceDuplicates(@NotNull PsiElement callElement, + public static void replaceDuplicates(@Nullable PsiElement callElement, @NotNull Editor editor, @NotNull Consumer> replacer, @NotNull List duplicates) { @@ -124,7 +125,12 @@ public class ExtractMethodHelper { .message("0.has.detected.1.code.fragments.in.this.file.that.can.be.replaced.with.a.call.to.extracted.method", ApplicationNamesInfo.getInstance().getProductName(), duplicates.size()); final boolean isUnittest = ApplicationManager.getApplication().isUnitTestMode(); - final Project project = callElement.getProject(); + final Project project = callElement != null ? callElement.getProject() : editor.getProject(); + if (project == null) { + Messages.showErrorDialog(editor.getComponent(), "Cannot find project."); + return; + } + final int exitCode = !isUnittest ? Messages.showYesNoDialog(project, message, RefactoringBundle.message("refactoring.extract.method.dialog.title"), Messages.getInformationIcon()) : diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/LightDirectoryIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/LightDirectoryIndex.java similarity index 75% rename from platform/lang-impl/src/com/intellij/ide/scratch/LightDirectoryIndex.java rename to platform/lang-impl/src/com/intellij/util/indexing/LightDirectoryIndex.java index 9b965a02128b..d6a828370c3a 100644 --- a/platform/lang-impl/src/com/intellij/ide/scratch/LightDirectoryIndex.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/LightDirectoryIndex.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,8 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.ide.scratch; +package com.intellij.util.indexing; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.fileTypes.FileTypeEvent; import com.intellij.openapi.fileTypes.FileTypeListener; import com.intellij.openapi.fileTypes.FileTypeManager; @@ -23,7 +25,7 @@ import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.VirtualFileWithId; import com.intellij.openapi.vfs.newvfs.BulkFileListener; import com.intellij.openapi.vfs.newvfs.events.VFileEvent; -import com.intellij.util.PairConsumer; +import com.intellij.util.Consumer; import com.intellij.util.containers.ConcurrentIntObjectMap; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.messages.MessageBusConnection; @@ -33,23 +35,27 @@ import org.jetbrains.annotations.Nullable; import java.util.List; /** - * This is a light version of DirectoryIndexImpl. + * This is a light version of DirectoryIndexImpl * * @author gregsh */ -abstract class LightDirectoryIndex { +public final class LightDirectoryIndex { private final ConcurrentIntObjectMap myInfoCache = ContainerUtil.createConcurrentIntObjectMap(); private final T myDefValue; + private final Consumer> myInitializer; - public LightDirectoryIndex(@NotNull MessageBusConnection connection, @NotNull T defValue) { + public LightDirectoryIndex(@NotNull Disposable parentDisposable, @NotNull T defValue, @NotNull Consumer> initializer) { myDefValue = defValue; - reinitRoots(); + myInitializer = initializer; + resetIndex(); + MessageBusConnection connection = ApplicationManager.getApplication().getMessageBus().connect(parentDisposable); connection.subscribe(FileTypeManager.TOPIC, new FileTypeListener.Adapter() { @Override public void fileTypesChanged(@NotNull FileTypeEvent event) { - reinitRoots(); + resetIndex(); } }); + connection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener() { @Override public void before(@NotNull List events) { @@ -60,7 +66,7 @@ abstract class LightDirectoryIndex { for (VFileEvent event : events) { VirtualFile file = event.getFile(); if (file == null || file.isDirectory()) { - reinitRoots(); + resetIndex(); break; } } @@ -68,15 +74,20 @@ abstract class LightDirectoryIndex { }); } - public void reinitRoots() { + public void resetIndex() { myInfoCache.clear(); - collectRoots((file, info) -> cacheInfo(file, info)); + myInitializer.consume(this); } - protected abstract void collectRoots(@NotNull PairConsumer consumer); + public void putInfo(@Nullable VirtualFile file, @NotNull T value) { + if (!(file instanceof VirtualFileWithId)) return; + cacheInfo(file, value); + } @NotNull - public T getInfoForFile(@NotNull VirtualFile file) { + public T getInfoForFile(@Nullable VirtualFile file) { + if (!(file instanceof VirtualFileWithId)) return myDefValue; + VirtualFile dir; if (!file.isDirectory()) { T info = getCachedInfo(file); diff --git a/platform/platform-api/src/com/intellij/ui/EffectPainter.java b/platform/platform-api/src/com/intellij/ui/EffectPainter.java index d245349105a0..b22244b9644e 100644 --- a/platform/platform-api/src/com/intellij/ui/EffectPainter.java +++ b/platform/platform-api/src/com/intellij/ui/EffectPainter.java @@ -39,8 +39,7 @@ public enum EffectPainter implements RegionPainter { } else if (paint != null && width > 0 && height > 0) { int h = height > 6 && Registry.is("ide.text.effect.wave.new.scale") ? height >> 1 : 3; - double pos = Registry.doubleValue("ide.text.effect.line.new.pos"); - y += height < 3 ? 1 : (int)((double)height - h * pos); + y += height - 1 - h / 2; g.setPaint(paint); g.drawLine(x, y, x + width, y); } @@ -60,25 +59,17 @@ public enum EffectPainter implements RegionPainter { WavePainter.forColor(g.getColor()).paint(g, x, x + width, y + height); } else if (paint != null && width > 0 && height > 0) { - boolean simple = height < 5; - int h = height > 6 && Registry.is("ide.text.effect.wave.new.scale") ? height >> 1 : 3; - if (h != height) { - y += height - h; - height = h; - } g = (Graphics2D)g.create(x, y, width, height); - g.clipRect(0, -1, width, height + 1); // 1px for Retina painting - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g.setPaint(paint); - - int length = 2 * height - 2; // the spatial period of the wave + g.clipRect(0, 0, width, height); + int h = height > 6 && Registry.is("ide.text.effect.wave.new.scale") ? height >> 1 : 3; + int length = 2 * h - 2; // the spatial period of the wave double dx = -((x % length + length) % length); // normalize - double upper = 0; + double upper = height - h; double lower = height - 1; Path2D path = new Path2D.Double(); path.moveTo(dx, lower); - if (simple) { + if (height < 6) { g.setStroke(STROKE); double size = (double)length / 2; while (true) { @@ -91,7 +82,7 @@ public enum EffectPainter implements RegionPainter { else { double size = (double)length / 4; double prev = dx - size / 2; - double center = lower / 2; + double center = (upper + lower) / 2; while (true) { path.quadTo(prev += size, lower, dx += size, center); if (dx > width) break; @@ -103,6 +94,8 @@ public enum EffectPainter implements RegionPainter { if (dx > width) break; } } + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g.setPaint(paint); g.draw(path); g.dispose(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 7d53a913907b..8c5255d63f3b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -112,7 +112,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App private int myInEditorPaintCounter; // EDT only private final long myStartTime; @Nullable - private final Splash mySplash; + private Splash mySplash; private boolean myDoNotSave; private volatile boolean myDisposeInProgress; @@ -420,6 +420,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App token.finish(); } myLoaded = true; + mySplash = null; createLocatorFile(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowShadowPainter.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowShadowPainter.java index 3828fcf90257..5a6784a55596 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowShadowPainter.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowShadowPainter.java @@ -21,38 +21,82 @@ import com.intellij.util.ui.UIUtil; import javax.swing.*; import java.awt.*; +import java.awt.event.AWTEventListener; +import java.util.List; +import java.util.Objects; import static com.intellij.icons.AllIcons.Ide.Shadow.Popup.*; +import static com.intellij.util.containers.ContainerUtil.newArrayList; /** * @author Sergey.Malenkov */ -final class WindowShadowPainter extends AbstractPainter { +final class WindowShadowPainter extends AbstractPainter implements AWTEventListener { private static final ShadowPainter PAINTER = new ShadowPainter(Top, Top_right, Right, Bottom_right, Bottom, Bottom_left, Left, Top_left); + private static final long MASK = AWTEvent.WINDOW_EVENT_MASK | AWTEvent.WINDOW_STATE_EVENT_MASK | AWTEvent.COMPONENT_EVENT_MASK; + private List myShadows; + private Component myComponent; - WindowShadowPainter() { - setNeedsRepaint(true); + @Override + public boolean needsRepaint() { + return true; + } + + @Override + public void eventDispatched(AWTEvent event) { + Component component = myComponent; + if (component == null) return; + Window window = UIUtil.getWindow(component); + if (window == null) return; + Object source = event.getSource(); + if (source instanceof Window && SwingUtilities.isDescendingFrom((Window)source, window)) { + List shadows = myShadows; + myShadows = getShadows(component, window); + if (!Objects.equals(myShadows, shadows)) component.repaint(); + } } @Override public void executePaint(Component component, Graphics2D g) { Window window = UIUtil.getWindow(component); if (window != null) { - Point point = new Point(); - SwingUtilities.convertPointToScreen(point, component); - paintShadows(component, g, point, window.getOwnedWindows()); - setNeedsRepaint(true); + if (myComponent != component) { + boolean add = myComponent == null; + myComponent = component; + myShadows = getShadows(component, window); + if (add) Toolkit.getDefaultToolkit().addAWTEventListener(this, MASK); + } + List shadows = myShadows; + if (shadows != null) { + for (Rectangle bounds : shadows) { + PAINTER.paintShadow(component, g, bounds.x, bounds.y, bounds.width, bounds.height); + } + } + } + else if (myComponent != null) { + Toolkit.getDefaultToolkit().removeAWTEventListener(this); + myComponent = null; } } - private static void paintShadows(Component component, Graphics2D g, Point point, Window... windows) { + private static List getShadows(Component component, Window window) { + Point point = new Point(); + SwingUtilities.convertPointToScreen(point, component); + return getShadows(null, point, window.getOwnedWindows()); + } + + private static List getShadows(List list, Point point, Window... windows) { if (windows != null) { for (Window window : windows) { Rectangle bounds = getShadowBounds(point, window); - if (bounds != null) PAINTER.paintShadow(component, g, bounds.x, bounds.y, bounds.width, bounds.height); - paintShadows(component, g, point, window.getOwnedWindows()); + if (bounds != null) { + if (list == null) list = newArrayList(); + list.add(bounds); + } + list = getShadows(list, point, window.getOwnedWindows()); } } + return list; } private static Rectangle getShadowBounds(Point point, Window window) { diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index f292a189d63d..5a3e3d9b91a4 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -359,6 +359,7 @@ + diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index 173902c9773b..12af5cd126b1 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -768,8 +768,6 @@ editor.rainbow.identifiers.description=Rainbow identifiers in editor ide.text.effect.line.new=false ide.text.effect.line.new.description=Enables new line painter for text -ide.text.effect.line.new.pos=0.5 -ide.text.effect.line.new.pos.description=Changes a line position ide.text.effect.wave.new=false ide.text.effect.wave.new.description=Enables new wave painter for text ide.text.effect.wave.new.scale=false diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml index 60a07b4452ab..e319cbf64794 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml @@ -2385,7 +2385,7 @@ level="WARNING" implementationClass="com.siyeh.ig.style.ConstantOnRHSOfComparisonInspection"/> #ref is too br return.this.problem.descriptor=Return of #ref #loc constant.on.lhs.of.comparison.problem.descriptor=#ref: constant on left side of comparison #loc constant.on.rhs.of.comparison.problem.descriptor=#ref: constant on right side of comparison #loc -control.flow.statement.without.braces.problem.descriptor=#ref without braces #loc +control.flow.statement.without.braces.problem.descriptor={0} without braces #loc missorted.modifiers.problem.descriptor=Missorted modifiers #ref #loc cstyle.array.variable.declaration.problem.descriptor=C-style array declaration of {0, choice, 1#field|2#parameter|3#local variable} #ref #loc cstyle.array.method.declaration.problem.descriptor=C-style array declaration of the return type of method #ref()#loc @@ -1335,6 +1335,7 @@ introduce.variable.quickfix=Introduce variable introduce.variable.may.change.semantics.quickfix=Introduce variable (may change semantics) flip.comparison.quickfix=Flip comparison control.flow.statement.without.braces.add.quickfix=Add braces +control.flow.statement.without.braces.message=Add braces to ''{0}'' statement extends.object.remove.quickfix=Remove redundant 'extends Object' implicit.call.to.super.ignore.option=Ignore for direct subclasses of 'java.lang.Object' implicit.call.to.super.make.explicit.quickfix=Make call to 'super()' explicit diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/BaseInspectionVisitor.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/BaseInspectionVisitor.java index 06c90eacee02..4d4d8aae6fbf 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/BaseInspectionVisitor.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/BaseInspectionVisitor.java @@ -15,6 +15,8 @@ */ package com.siyeh.ig; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.codeInspection.ProblemHighlightType; import com.intellij.codeInspection.ProblemsHolder; import com.intellij.openapi.util.TextRange; @@ -183,10 +185,7 @@ public abstract class BaseInspectionVisitor extends JavaElementVisitor { if (!location.isPhysical() || location.getTextLength() == 0 && !(location instanceof PsiFile)) { return; } - final InspectionGadgetsFix[] fixes = createFixes(infos); - for (InspectionGadgetsFix fix : fixes) { - fix.setOnTheFly(onTheFly); - } + final LocalQuickFix[] fixes = createAndInitFixes(infos); final String description = inspection.buildErrorString(infos); holder.registerProblem(location, description, highlightType, fixes); } @@ -201,13 +200,30 @@ public abstract class BaseInspectionVisitor extends JavaElementVisitor { if (location.getTextLength() == 0 || length == 0) { return; } + final LocalQuickFix[] fixes = createAndInitFixes(infos); + final String description = inspection.buildErrorString(infos); + final TextRange range = new TextRange(offset, offset + length); + holder.registerProblem(location, description, highlightType, range, fixes); + } + + protected final void registerErrorAtRange(@NotNull PsiElement startLocation, @NotNull PsiElement endLocation, Object... infos) { + if (startLocation.getTextLength() == 0 && startLocation == endLocation) { + return; + } + final LocalQuickFix[] fixes = createAndInitFixes(infos); + final String description = inspection.buildErrorString(infos); + final ProblemDescriptor problemDescriptor = holder.getManager() + .createProblemDescriptor(startLocation, endLocation, description, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, onTheFly, fixes); + holder.registerProblem(problemDescriptor); + } + + @NotNull + private LocalQuickFix[] createAndInitFixes(Object[] infos) { final InspectionGadgetsFix[] fixes = createFixes(infos); for (InspectionGadgetsFix fix : fixes) { fix.setOnTheFly(onTheFly); } - final String description = inspection.buildErrorString(infos); - final TextRange range = new TextRange(offset, offset + length); - holder.registerProblem(location, description, highlightType, range, fixes); + return fixes; } @NotNull diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspection.java index 78804d9e766d..c450f7f96ee7 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspection.java @@ -15,8 +15,12 @@ */ package com.siyeh.ig.style; +import com.intellij.codeHighlighting.HighlightDisplayLevel; +import com.intellij.codeInsight.daemon.HighlightDisplayKey; +import com.intellij.codeInspection.InspectionProfile; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; +import com.intellij.profile.codeInspection.InspectionProjectProfileManager; import com.intellij.psi.*; import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; @@ -24,12 +28,17 @@ import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.PsiReplacementUtil; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; public class ControlFlowStatementWithoutBracesInspection extends BaseInspection { + private static final String DO_TEXT = "do"; + private static final String ELSE_TEXT = "else"; + private static final String FOR_TEXT = "for"; + private static final String IF_TEXT = "if"; + private static final String WHILE_TEXT = "while"; + @Override @NotNull public String getDisplayName() { @@ -41,38 +50,52 @@ public class ControlFlowStatementWithoutBracesInspection @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( - "control.flow.statement.without.braces.problem.descriptor"); + "control.flow.statement.without.braces.problem.descriptor", infos); } @Override public InspectionGadgetsFix buildFix(Object... infos) { - return new ControlFlowStatementFix(); + if (infos.length == 1 && infos[0] instanceof String) { + return new ControlFlowStatementFix((String)infos[0]); + } + return null; } private static class ControlFlowStatementFix extends InspectionGadgetsFix { + private final String myKeywordText; + + public ControlFlowStatementFix(String keywordText) { + myKeywordText = keywordText; + } @Override @NotNull public String getName() { return InspectionGadgetsBundle.message( - "control.flow.statement.without.braces.add.quickfix"); + "control.flow.statement.without.braces.message", myKeywordText); } @Override @NotNull public String getFamilyName() { - return getName(); + return InspectionGadgetsBundle.message( + "control.flow.statement.without.braces.add.quickfix"); } @Override protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { - final PsiElement element = descriptor.getPsiElement(); + final PsiElement element = descriptor.getStartElement(); final PsiElement parent = element.getParent(); - if (!(parent instanceof PsiStatement)) { + final PsiStatement statement; + if (element instanceof PsiStatement) { + statement = (PsiStatement)element; + } + else if ((parent instanceof PsiStatement)) { + statement = (PsiStatement)parent; + } + else { return; } - final PsiStatement statement = (PsiStatement)parent; - @NonNls final String elementText = element.getText(); final PsiStatement statementWithoutBraces; if (statement instanceof PsiLoopStatement) { final PsiLoopStatement loopStatement = @@ -81,7 +104,10 @@ public class ControlFlowStatementWithoutBracesInspection } else if (statement instanceof PsiIfStatement) { final PsiIfStatement ifStatement = (PsiIfStatement)statement; - if ("if".equals(elementText)) { + if (element == ifStatement.getElseElement()) { + statementWithoutBraces = ifStatement.getElseBranch(); + } + else { statementWithoutBraces = ifStatement.getThenBranch(); if (statementWithoutBraces == null) { return; @@ -93,9 +119,6 @@ public class ControlFlowStatementWithoutBracesInspection nextSibling.delete(); } } - else { - statementWithoutBraces = ifStatement.getElseBranch(); - } } else { return; @@ -111,11 +134,18 @@ public class ControlFlowStatementWithoutBracesInspection @Override public BaseInspectionVisitor buildVisitor() { - return new ControlFlowStatementVisitor(); + final String shortName = getShortName(); + final HighlightDisplayKey key = HighlightDisplayKey.find(shortName); + return new ControlFlowStatementVisitor(key); } private static class ControlFlowStatementVisitor extends BaseInspectionVisitor { + private HighlightDisplayKey myKey; + + public ControlFlowStatementVisitor(HighlightDisplayKey key) { + myKey = key; + } @Override public void visitDoWhileStatement(PsiDoWhileStatement statement) { @@ -124,7 +154,7 @@ public class ControlFlowStatementWithoutBracesInspection if (body == null || body instanceof PsiBlockStatement) { return; } - registerStatementError(statement); + registerKeywordOrStatementError(statement, DO_TEXT); } @Override @@ -134,7 +164,7 @@ public class ControlFlowStatementWithoutBracesInspection if (body == null || body instanceof PsiBlockStatement) { return; } - registerStatementError(statement); + registerKeywordOrStatementError(statement, FOR_TEXT); } @Override @@ -144,7 +174,7 @@ public class ControlFlowStatementWithoutBracesInspection if (body == null || body instanceof PsiBlockStatement) { return; } - registerStatementError(statement); + registerKeywordOrStatementError(statement, FOR_TEXT); } @Override @@ -154,8 +184,15 @@ public class ControlFlowStatementWithoutBracesInspection if (thenBranch == null) { return; } + boolean highlightOnlyKeyword = isHighlightOnlyKeyword(statement); if (!(thenBranch instanceof PsiBlockStatement)) { - registerStatementError(statement); + if (highlightOnlyKeyword) { + registerStatementError(statement, IF_TEXT); + } + else { + final PsiElement startElement = statement.getFirstChild(); + registerErrorAtRange(startElement != null ? startElement : thenBranch, thenBranch, IF_TEXT); + } } final PsiStatement elseBranch = statement.getElseBranch(); if (elseBranch == null) { @@ -167,7 +204,12 @@ public class ControlFlowStatementWithoutBracesInspection if (elseKeyword == null) { return; } - registerError(elseKeyword); + if (highlightOnlyKeyword) { + registerError(elseKeyword, ELSE_TEXT); + } + else { + registerErrorAtRange(elseKeyword, elseBranch, ELSE_TEXT); + } } } @@ -178,7 +220,30 @@ public class ControlFlowStatementWithoutBracesInspection if (body == null || body instanceof PsiBlockStatement) { return; } - registerStatementError(statement); + registerKeywordOrStatementError(statement, WHILE_TEXT); + } + + private void registerKeywordOrStatementError(PsiStatement statement, String text) { + boolean highlightOnlyKeyword = isHighlightOnlyKeyword(statement); + if (highlightOnlyKeyword) { + registerStatementError(statement, text); + } + else { + registerError(statement, text); + } + } + + private boolean isHighlightOnlyKeyword(PsiElement element) { + if (!isOnTheFly()) { + return true; + } + if (myKey != null) { + final Project project = element.getProject(); + final InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile(); + HighlightDisplayLevel errorLevel = profile.getErrorLevel(myKey, element); + return !HighlightDisplayLevel.DO_NOT_SHOW.equals(errorLevel); + } + return false; } } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoBody.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoBody.after.java new file mode 100644 index 000000000000..f6a1323f4e5f --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoBody.after.java @@ -0,0 +1,9 @@ +class T { + void f(String[] a) { + int j = 0; + do { + System.out.println(a[j++]); + } + while (j < a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoBody.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoBody.java new file mode 100644 index 000000000000..d06d1f35f337 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoBody.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + int j = 0; + do System.out.println(a[j++]); + while (j < a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoExpression.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoExpression.after.java new file mode 100644 index 000000000000..f6a1323f4e5f --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoExpression.after.java @@ -0,0 +1,9 @@ +class T { + void f(String[] a) { + int j = 0; + do { + System.out.println(a[j++]); + } + while (j < a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoExpression.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoExpression.java new file mode 100644 index 000000000000..eaedfb956318 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoExpression.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + int j = 0; + do System.out.println(a[j++]); + while (j < a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoMiddle.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoMiddle.after.java new file mode 100644 index 000000000000..f6a1323f4e5f --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoMiddle.after.java @@ -0,0 +1,9 @@ +class T { + void f(String[] a) { + int j = 0; + do { + System.out.println(a[j++]); + } + while (j < a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoMiddle.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoMiddle.java new file mode 100644 index 000000000000..ae9eeaa86d2c --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoMiddle.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + int j = 0; + do System.out.println(a[j++]); + while (j < a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachBody.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachBody.after.java new file mode 100644 index 000000000000..f3fc6d139b34 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachBody.after.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + for (String s : a) { + System.out.println(s); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachBody.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachBody.java new file mode 100644 index 000000000000..00b8c9f34831 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachBody.java @@ -0,0 +1,6 @@ +class T { + void f(String[] a) { + for (String s : a) + System.out.println(s); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachExpression.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachExpression.after.java new file mode 100644 index 000000000000..f3fc6d139b34 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachExpression.after.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + for (String s : a) { + System.out.println(s); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachExpression.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachExpression.java new file mode 100644 index 000000000000..c0aa6b8c763a --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachExpression.java @@ -0,0 +1,6 @@ +class T { + void f(String[] a) { + for (String s : a) + System.out.println(s); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachKeyword.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachKeyword.after.java new file mode 100644 index 000000000000..f3fc6d139b34 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachKeyword.after.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + for (String s : a) { + System.out.println(s); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachKeyword.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachKeyword.java new file mode 100644 index 000000000000..c10dc13fc45a --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachKeyword.java @@ -0,0 +1,6 @@ +class T { + void f(String[] a) { + for (String s : a) + System.out.println(s); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForIndex.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForIndex.after.java new file mode 100644 index 000000000000..67ba7f8d5b20 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForIndex.after.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + for (int i = 0; i < a.length; i++) { + System.out.println(a[i]); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForIndex.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForIndex.java new file mode 100644 index 000000000000..7e6eb6a3c5c0 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForIndex.java @@ -0,0 +1,6 @@ +class T { + void f(String[] a) { + for (int i = 0; i < a.length; i++) + System.out.println(a[i]); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfBody.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfBody.after.java new file mode 100644 index 000000000000..3ac6e8522f60 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfBody.after.java @@ -0,0 +1,8 @@ +class T { + void f(String[] a) { + if (a.length == 0) { + System.out.println("no"); + } else + System.out.println(a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfBody.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfBody.java new file mode 100644 index 000000000000..e6167755562d --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfBody.java @@ -0,0 +1,8 @@ +class T { + void f(String[] a) { + if (a.length == 0) + System.out.println("no"); + else + System.out.println(a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseBody.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseBody.after.java new file mode 100644 index 000000000000..0ce38894f421 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseBody.after.java @@ -0,0 +1,9 @@ +class T { + void f(String[] a) { + if (a.length == 0) + System.out.println("no"); + else { + System.out.println(a.length); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseBody.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseBody.java new file mode 100644 index 000000000000..3679e2b894a4 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseBody.java @@ -0,0 +1,8 @@ +class T { + void f(String[] a) { + if (a.length == 0) + System.out.println("no"); + else + System.out.println(a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseKeyword.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseKeyword.after.java new file mode 100644 index 000000000000..0ce38894f421 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseKeyword.after.java @@ -0,0 +1,9 @@ +class T { + void f(String[] a) { + if (a.length == 0) + System.out.println("no"); + else { + System.out.println(a.length); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseKeyword.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseKeyword.java new file mode 100644 index 000000000000..c8affc66625c --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseKeyword.java @@ -0,0 +1,8 @@ +class T { + void f(String[] a) { + if (a.length == 0) + System.out.println("no"); + else + System.out.println(a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfKeyword.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfKeyword.after.java new file mode 100644 index 000000000000..3ac6e8522f60 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfKeyword.after.java @@ -0,0 +1,8 @@ +class T { + void f(String[] a) { + if (a.length == 0) { + System.out.println("no"); + } else + System.out.println(a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfKeyword.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfKeyword.java new file mode 100644 index 000000000000..dfbe50f8feb3 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfKeyword.java @@ -0,0 +1,8 @@ +class T { + void f(String[] a) { + if (a.length == 0) + System.out.println("no"); + else + System.out.println(a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfMiddle.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfMiddle.java new file mode 100644 index 000000000000..d01a75370a53 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfMiddle.java @@ -0,0 +1,8 @@ +class T { + void f(String[] a) { + if (a.length == 0) + System.out.println("no"); + else + System.out.println(a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfBody.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfBody.after.java new file mode 100644 index 000000000000..36d1699c71e6 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfBody.after.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + if (a.length == 0) { + System.out.println("no"); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfBody.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfBody.java new file mode 100644 index 000000000000..5b5c4961efad --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfBody.java @@ -0,0 +1,6 @@ +class T { + void f(String[] a) { + if (a.length == 0) + System.out.println("no"); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfExpression.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfExpression.after.java new file mode 100644 index 000000000000..36d1699c71e6 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfExpression.after.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + if (a.length == 0) { + System.out.println("no"); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfExpression.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfExpression.java new file mode 100644 index 000000000000..e1eb7631230a --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfExpression.java @@ -0,0 +1,6 @@ +class T { + void f(String[] a) { + if (a.length == 0) + System.out.println("no"); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfKeyword.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfKeyword.after.java new file mode 100644 index 000000000000..36d1699c71e6 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfKeyword.after.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + if (a.length == 0) { + System.out.println("no"); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfKeyword.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfKeyword.java new file mode 100644 index 000000000000..111f51f1b28c --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfKeyword.java @@ -0,0 +1,6 @@ +class T { + void f(String[] a) { + if (a.length == 0) + System.out.println("no"); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/While.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/While.after.java new file mode 100644 index 000000000000..6ca70967cdcf --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/While.after.java @@ -0,0 +1,8 @@ +class T { + void f(String[] a) { + int k = 0; + while (k < a.length) { + System.out.println(a[k++]); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/While.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/While.java new file mode 100644 index 000000000000..70519665401c --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/While.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + int k = 0; + while (k < a.length) + System.out.println(a[k++]); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/WhileOutside.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/WhileOutside.java new file mode 100644 index 000000000000..0e098b101df4 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/WhileOutside.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + int k = 0; + while (k < a.length) + System.out.println(a[k++]); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/statements_without_braces/ControlFlowStatements.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/statements_without_braces/ControlFlowStatements.java new file mode 100644 index 000000000000..5b6f9a1da573 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/statements_without_braces/ControlFlowStatements.java @@ -0,0 +1,29 @@ +class T { + void f(String[] a) { + for (String s : a) + System.out.println(s); + + if (a.length == 0) + System.out.println("no"); + else + System.out.println(a.length); + + for (int i = 0; i < a.length; i++) + System.out.println(a[i]); + + int j = 0; + do System.out.println(a[j++]); + while (j < a.length); + + int k = 0; + while (k < a.length) + System.out.println(a[k++]); + + if (a.length == 0) + System.out.println("no"); + + if (a.length == 0) { + } else + System.out.println(a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/statements_without_braces/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/statements_without_braces/expected.xml new file mode 100644 index 000000000000..e5869a1c602e --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/statements_without_braces/expected.xml @@ -0,0 +1,60 @@ + + + + + ControlFlowStatements.java + 3 + Control flow statement without braces + <code>for</code> without braces #loc + + + + ControlFlowStatements.java + 6 + Control flow statement without braces + <code>if</code> without braces #loc + + + + ControlFlowStatements.java + 8 + Control flow statement without braces + <code>else</code> without braces #loc + + + + ControlFlowStatements.java + 11 + Control flow statement without braces + <code>for</code> without braces #loc + + + + ControlFlowStatements.java + 15 + Control flow statement without braces + <code>do</code> without braces #loc + + + + ControlFlowStatements.java + 19 + Control flow statement without braces + <code>while</code> without braces #loc + + + + ControlFlowStatements.java + 22 + Control flow statement without braces + <code>if</code> without braces #loc + + + + ControlFlowStatements.java + 26 + Control flow statement without braces + <code>else</code> without braces #loc + + + \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/IGQuickFixesTestCase.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/IGQuickFixesTestCase.java index b281d4bfe380..f184c962d5ac 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/IGQuickFixesTestCase.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/IGQuickFixesTestCase.java @@ -116,8 +116,9 @@ public abstract class IGQuickFixesTestCase extends JavaCodeInsightFixtureTestCas } public IntentionAction findIntention(@NotNull final String hint) { + final List allIntentions = myFixture.getAvailableIntentions(); final List intentions = - ContainerUtil.findAll(myFixture.getAvailableIntentions(), + ContainerUtil.findAll(allIntentions, intentionAction -> intentionAction instanceof QuickFixWrapper && intentionAction.getText().equals(hint)); Assert.assertFalse("\"" + hint + "\" not in " + intentions, intentions.isEmpty()); diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/braces/ControlFlowStatementWithoutBracesFixTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/braces/ControlFlowStatementWithoutBracesFixTest.java new file mode 100644 index 000000000000..2d1f76a267fc --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/braces/ControlFlowStatementWithoutBracesFixTest.java @@ -0,0 +1,75 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ig.fixes.braces; + +import com.siyeh.InspectionGadgetsBundle; +import com.siyeh.ig.BaseInspection; +import com.siyeh.ig.IGQuickFixesTestCase; +import com.siyeh.ig.style.ControlFlowStatementWithoutBracesInspection; + +/** + * @author Pavel.Dolgov + */ +public class ControlFlowStatementWithoutBracesFixTest extends IGQuickFixesTestCase { + + public void testSimpleIfBody() { doTest("if"); } + public void testSimpleIfExpression() { doTest("if"); } + public void testSimpleIfKeyword() { doTest("if"); } + + public void testFullIfBody() { doTest("if"); } + public void testFullIfKeyword() { doTest("if"); } + public void testFullIfElseBody() { doTest("else"); } + public void testFullIfElseKeyword() { doTest("else"); } + public void testFullIfMiddle() { assertQuickfixNotAvailable(getMessagePrefix()); } + + public void testDoBody() { doTest("do"); } + public void testDoExpression() { doTest("do"); } + public void testDoMiddle() { doTest("do"); } + + public void testForEachBody() { doTest("for"); } + public void testForEachExpression() { doTest("for"); } + public void testForEachKeyword() { doTest("for"); } + public void testForIndex() { doTest("for"); } + + public void testWhile() { doTest("while"); } + public void testWhileOutside() { assertQuickfixNotAvailable(getMessagePrefix()); } + + @Override + protected void setUp() throws Exception { + super.setUp(); + myRelativePath = "statement_without_braces"; + } + + @Override + protected BaseInspection getInspection() { + return new ControlFlowStatementWithoutBracesInspection(); + } + + protected void doTest(String keyword) { + super.doTest(getMessage(keyword)); + } + + private static String getMessage(String keyword) { + return InspectionGadgetsBundle.message("control.flow.statement.without.braces.message", keyword); + } + + private static String getMessagePrefix() { + final String message = InspectionGadgetsBundle.message("control.flow.statement.without.braces.message", "@"); + final int index = message.indexOf("@"); + if (index >= 0) return message.substring(0, index); + return message; + } +} diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspectionTest.java new file mode 100644 index 000000000000..d7ac2b40792e --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspectionTest.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ig.style; + +import com.siyeh.ig.IGInspectionTestCase; + +/** + * @author Pavel.Dolgov + */ +public class ControlFlowStatementWithoutBracesInspectionTest extends IGInspectionTestCase { + public void test() { + doTest("com/siyeh/igtest/style/statements_without_braces", new ControlFlowStatementWithoutBracesInspection()); + } +} diff --git a/plugins/IntentionPowerPak/src/META-INF/IntentionPowerPack.xml b/plugins/IntentionPowerPak/src/META-INF/IntentionPowerPack.xml index f53563be74fe..9ed5d7fa3a5d 100644 --- a/plugins/IntentionPowerPak/src/META-INF/IntentionPowerPack.xml +++ b/plugins/IntentionPowerPak/src/META-INF/IntentionPowerPack.xml @@ -351,11 +351,6 @@ com.siyeh.IntentionPowerPackBundle intention.category.control.flow - - com.siyeh.ipp.braces.AddBracesIntention - com.siyeh.IntentionPowerPackBundle - intention.category.control.flow - com.siyeh.ipp.braces.RemoveBracesIntention com.siyeh.IntentionPowerPackBundle diff --git a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties index 17284cd00e7f..30b6f9c3a113 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties +++ b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties @@ -90,7 +90,6 @@ flip.comparison.intention.family.name=Flip Comparison flip.conjunction.intention.family.name=Flip Conjunction Operands negate.comparison.intention.family.name=Negate Comparison remove.braces.intention.family.name=Remove Braces -add.braces.intention.family.name=Add Braces flip.commutative.method.call.intention.family.name=Flip Commutative Method Call constant.subexpression.intention.family.name=Compute Constant Value for Subexpression extract.increment.intention.family.name=Extract Increment @@ -172,7 +171,6 @@ flip.smth.intention.name1=Flip ''{0}'' (changes semantics) flip.comparison.intention.name=Flip ''{0}'' to ''{1}'' negate.comparison.intention.name=Negate ''{0}'' negate.comparison.intention.name1=Negate ''{0}'' to ''{1}'' -add.braces.intention.name=Add braces to ''{0}'' statement remove.braces.intention.name=Remove braces from ''{0}'' statement flip.commutative.method.call.intention.name=Flip ''.{0}()'' flip.commutative.method.call.intention.name1=Flip ''.{0}()'' (may change semantics) diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/AddBracesIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/AddBracesIntention.java deleted file mode 100644 index f51759f6a171..000000000000 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/AddBracesIntention.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2003-2006 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.siyeh.ipp.braces; - -import com.intellij.psi.*; -import com.intellij.util.IncorrectOperationException; -import com.siyeh.ig.PsiReplacementUtil; -import com.siyeh.ipp.base.PsiElementPredicate; -import org.jetbrains.annotations.NotNull; - -public class AddBracesIntention extends BaseBracesIntention { - - @NotNull - protected PsiElementPredicate getElementPredicate() { - return new PsiElementPredicate() { - @Override - public boolean satisfiedBy(PsiElement element) { - final PsiStatement statement = getSurroundingStatement(element); - return statement != null && !(statement instanceof PsiBlockStatement); - } - }; - } - - @NotNull - @Override - protected String getMessageKey() { - return "add.braces.intention.name"; - } - - protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { - final PsiStatement statement = getSurroundingStatement(element); - if (statement == null) { - return; - } - final String newStatement = "{\n" + statement.getText() + "\n}"; - PsiReplacementUtil.replaceStatement(statement, newStatement); - } -} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/AddBracesIntention/after.java.template b/plugins/IntentionPowerPak/src/intentionDescriptions/AddBracesIntention/after.java.template deleted file mode 100644 index 7777953c60cc..000000000000 --- a/plugins/IntentionPowerPak/src/intentionDescriptions/AddBracesIntention/after.java.template +++ /dev/null @@ -1,8 +0,0 @@ -public class X { - int f(boolean b) { - if (b) { - return 1; - } - return 0; - } -} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/AddBracesIntention/before.java.template b/plugins/IntentionPowerPak/src/intentionDescriptions/AddBracesIntention/before.java.template deleted file mode 100644 index d45dc00808ae..000000000000 --- a/plugins/IntentionPowerPak/src/intentionDescriptions/AddBracesIntention/before.java.template +++ /dev/null @@ -1,6 +0,0 @@ -public class X { - int f(boolean b) { - if (b) return 1; - return 0; - } -} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/AddBracesIntention/description.html b/plugins/IntentionPowerPak/src/intentionDescriptions/AddBracesIntention/description.html deleted file mode 100644 index fb832c3844f6..000000000000 --- a/plugins/IntentionPowerPak/src/intentionDescriptions/AddBracesIntention/description.html +++ /dev/null @@ -1,6 +0,0 @@ - - -This intention adds braces to control flow statements without -braces. - - diff --git a/plugins/devkit/testSources/PluginProjectWizardTest.java b/plugins/devkit/testSources/PluginProjectWizardTest.java index 1be1b1db4f8a..98e69e0071fe 100644 --- a/plugins/devkit/testSources/PluginProjectWizardTest.java +++ b/plugins/devkit/testSources/PluginProjectWizardTest.java @@ -18,7 +18,6 @@ package org.jetbrains.idea.devkit; import com.intellij.execution.RunManager; import com.intellij.execution.RunnerAndConfigurationSettings; import com.intellij.execution.configurations.ConfigurationType; -import com.intellij.ide.IdeBundle; import com.intellij.ide.projectWizard.NewProjectWizardTestCase; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; @@ -46,14 +45,4 @@ public class PluginProjectWizardTest extends NewProjectWizardTestCase { VirtualFile[] files = FileEditorManager.getInstance(project).getOpenFiles(); assertEquals(1, files.length); } - - public void testProjectWithoutSdk() throws Exception { - try { - createProjectFromTemplate(PluginModuleType.getInstance().getName(), null, null); - fail("Exception should be thrown"); - } - catch (Exception e) { - assertEquals(IdeBundle.message("prompt.confirm.project.no.jdk"), e.getMessage()); - } - } } diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java index 02c42d9cbb2f..cd44a84a63b1 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java +++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java @@ -26,6 +26,7 @@ import org.apache.http.message.BasicHeader; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.github.api.GithubConnection.PagedRequest; +import org.jetbrains.plugins.github.exceptions.GithubAuthenticationException; import org.jetbrains.plugins.github.exceptions.GithubConfusingException; import org.jetbrains.plugins.github.exceptions.GithubJsonException; import org.jetbrains.plugins.github.exceptions.GithubStatusCodeException; @@ -289,12 +290,12 @@ public class GithubApiUtil { try { repos.addAll(getMembershipRepos(connection)); } - catch (GithubStatusCodeException ignore) { + catch (GithubAuthenticationException | GithubStatusCodeException ignore) { } try { repos.addAll(getWatchedRepos(connection)); } - catch (GithubStatusCodeException ignore) { + catch (GithubAuthenticationException | GithubStatusCodeException ignore) { } return repos; diff --git a/plugins/settings-repository/src/BaseRepositoryManager.kt b/plugins/settings-repository/src/BaseRepositoryManager.kt index 8d8ca968ebe0..35029871070e 100644 --- a/plugins/settings-repository/src/BaseRepositoryManager.kt +++ b/plugins/settings-repository/src/BaseRepositoryManager.kt @@ -130,7 +130,7 @@ abstract class BaseRepositoryManager(protected val dir: Path) : RepositoryManage */ protected abstract fun addToIndex(file: Path, path: String, content: ByteArray, size: Int) - override fun delete(path: String) { + override fun delete(path: String): Boolean { LOG.debug { "Remove $path"} lock.write { @@ -138,8 +138,11 @@ abstract class BaseRepositoryManager(protected val dir: Path) : RepositoryManage // delete could be called for non-existent file if (file.exists()) { delete(file, path) + return true } } + + return false } private fun delete(file: Path, path: String) { diff --git a/plugins/settings-repository/src/IcsManager.kt b/plugins/settings-repository/src/IcsManager.kt index 7e6217b1ed84..568156f900d7 100644 --- a/plugins/settings-repository/src/IcsManager.kt +++ b/plugins/settings-repository/src/IcsManager.kt @@ -242,23 +242,26 @@ class IcsApplicationLoadListener : ApplicationLoadListener { val repositoryManager = icsManager.repositoryManager if (repositoryManager.isRepositoryExists() && repositoryManager is GitRepositoryManager) { - if (repositoryManager.renameDirectory(linkedMapOf( - Pair("\$ROOT_CONFIG$", null), - Pair("_mac/\$ROOT_CONFIG$", "_mac"), - Pair("_windows/\$ROOT_CONFIG$", "_windows"), - Pair("_linux/\$ROOT_CONFIG$", "_linux"), - Pair("_freebsd/\$ROOT_CONFIG$", "_freebsd"), - Pair("_unix/\$ROOT_CONFIG$", "_unix"), - Pair("_unknown/\$ROOT_CONFIG$", "_unknown"), + val migrateSchemes = repositoryManager.renameDirectory(linkedMapOf( + Pair("\$ROOT_CONFIG$", null), + Pair("_mac/\$ROOT_CONFIG$", "_mac"), + Pair("_windows/\$ROOT_CONFIG$", "_windows"), + Pair("_linux/\$ROOT_CONFIG$", "_linux"), + Pair("_freebsd/\$ROOT_CONFIG$", "_freebsd"), + Pair("_unix/\$ROOT_CONFIG$", "_unix"), + Pair("_unknown/\$ROOT_CONFIG$", "_unknown"), - Pair("\$APP_CONFIG$", null), - Pair("_mac/\$APP_CONFIG$", "_mac"), - Pair("_windows/\$APP_CONFIG$", "_windows"), - Pair("_linux/\$APP_CONFIG$", "_linux"), - Pair("_freebsd/\$APP_CONFIG$", "_freebsd"), - Pair("_unix/\$APP_CONFIG$", "_unix"), - Pair("_unknown/\$APP_CONFIG$", "_unknown") - ))) { + Pair("\$APP_CONFIG$", null), + Pair("_mac/\$APP_CONFIG$", "_mac"), + Pair("_windows/\$APP_CONFIG$", "_windows"), + Pair("_linux/\$APP_CONFIG$", "_linux"), + Pair("_freebsd/\$APP_CONFIG$", "_freebsd"), + Pair("_unix/\$APP_CONFIG$", "_unix"), + Pair("_unknown/\$APP_CONFIG$", "_unknown") + )) + + val removeOtherXml = repositoryManager.delete("other.xml") + if (migrateSchemes || removeOtherXml) { // schedule push to avoid merge conflicts application.invokeLater({ icsManager.autoSyncManager.autoSync(force = true) }) } diff --git a/plugins/settings-repository/src/RepositoryManager.kt b/plugins/settings-repository/src/RepositoryManager.kt index 223471a6014f..c743e6ae9de1 100644 --- a/plugins/settings-repository/src/RepositoryManager.kt +++ b/plugins/settings-repository/src/RepositoryManager.kt @@ -46,7 +46,7 @@ interface RepositoryManager { */ fun write(path: String, content: ByteArray, size: Int): Boolean - fun delete(path: String) + fun delete(path: String): Boolean fun processChildren(path: String, filter: (name: String) -> Boolean, processor: (name: String, inputStream: InputStream) -> Boolean) diff --git a/python/psi-api/src/com/jetbrains/python/psi/impl/PyPsiUtils.java b/python/psi-api/src/com/jetbrains/python/psi/impl/PyPsiUtils.java index 46f07970447a..0f6eff9b153b 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/impl/PyPsiUtils.java +++ b/python/psi-api/src/com/jetbrains/python/psi/impl/PyPsiUtils.java @@ -113,6 +113,24 @@ public class PyPsiUtils { return PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace.class); } + /** + * Finds first non-whitespace sibling after given PSI element but stops at first whitespace containing line feed. + */ + @Nullable + public static PsiElement getNextNonWhitespaceSiblingOnSameLine(@NotNull PsiElement element) { + PsiElement cur = element.getNextSibling(); + while (cur != null) { + if (!(cur instanceof PsiWhiteSpace)) { + return cur; + } + else if (cur.textContains('\n')) { + break; + } + cur = cur.getNextSibling(); + } + return null; + } + /** * Finds first non-whitespace sibling after given AST node. */ diff --git a/python/src/com/jetbrains/python/psi/PyFileElementType.java b/python/src/com/jetbrains/python/psi/PyFileElementType.java index c89e07f22a99..3fc046be1632 100644 --- a/python/src/com/jetbrains/python/psi/PyFileElementType.java +++ b/python/src/com/jetbrains/python/psi/PyFileElementType.java @@ -62,7 +62,7 @@ public class PyFileElementType extends IStubFileElementType { @Override public int getStubVersion() { // Don't forget to update versions of indexes that use the updated stub-based elements - return 56; + return 57; } @Nullable diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index bdf133eed108..91e91d57f70e 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -890,6 +890,16 @@ public class PyUtil { } } + /** + * Returns the line comment that immediately precedes statement list of the given compound statement. Python parser ensures + * that it follows the statement header, i.e. it's directly after the colon, not on its own line. + */ + @Nullable + public static PsiComment getCommentOnHeaderLine(@NotNull PyStatementListContainer container) { + final PyStatementList statementList = container.getStatementList(); + return as(PyPsiUtils.getPrevNonWhitespaceSibling(statementList), PsiComment.class); + } + public static class KnownDecoratorProviderHolder { public static PyKnownDecoratorProvider[] KNOWN_DECORATOR_PROVIDERS = Extensions.getExtensions(PyKnownDecoratorProvider.EP_NAME); diff --git a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java index 0ffadde2d42c..3614bc520557 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java @@ -579,12 +579,12 @@ public class PyFunctionImpl extends PyBaseElementImpl implements @Nullable @Override public PsiComment getTypeComment() { - final PyStatementList statements = getStatementList(); - final PsiComment inlineComment = as(PyPsiUtils.getPrevNonWhitespaceSibling(statements), PsiComment.class); + final PsiComment inlineComment = PyUtil.getCommentOnHeaderLine(this); if (inlineComment != null && PyTypingTypeProvider.getTypeCommentValue(inlineComment.getText()) != null) { return inlineComment; } - + + final PyStatementList statements = getStatementList(); if (statements.getStatements().length != 0) { final PsiComment comment = as(statements.getFirstChild(), PsiComment.class); if (comment != null && PyTypingTypeProvider.getTypeCommentValue(comment.getText()) != null) { diff --git a/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java index 31c8f4711f32..28fc40cc833e 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java @@ -62,6 +62,8 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import static com.jetbrains.python.psi.PyUtil.as; + /** * @author yole */ @@ -682,34 +684,21 @@ public class PyTargetExpressionImpl extends PyBaseElementImpl