diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpTT.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpTT.java index b60b7bd85e19..c9f9b9bb8a09 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpTT.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpTT.java @@ -121,6 +121,7 @@ public interface RegExpTT { ESC_CTRL_CHARACTER, ESC_CHARACTER, CTRL_CHARACTER, + CTRL, UNICODE_CHAR, HEX_CHAR, BAD_HEX_VALUE, OCT_CHAR, BAD_OCT_VALUE, diff --git a/RegExpSupport/testData/RETest.xml b/RegExpSupport/testData/RETest.xml index 696057dc5826..10e04dcf80fa 100644 --- a/RegExpSupport/testData/RETest.xml +++ b/RegExpSupport/testData/RETest.xml @@ -603,6 +603,10 @@ \Q\j\E OK + + \c0 + OK + diff --git a/java/java-impl/src/com/intellij/codeEditor/JavaEditorFileSwapper.java b/java/java-impl/src/com/intellij/codeEditor/JavaEditorFileSwapper.java index 345383ea0326..0847c5412e54 100644 --- a/java/java-impl/src/com/intellij/codeEditor/JavaEditorFileSwapper.java +++ b/java/java-impl/src/com/intellij/codeEditor/JavaEditorFileSwapper.java @@ -19,6 +19,7 @@ import com.intellij.openapi.fileEditor.impl.EditorFileSwapper; import com.intellij.openapi.fileEditor.impl.EditorWithProviderComposite; import com.intellij.openapi.fileEditor.impl.text.TextEditorImpl; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; @@ -66,7 +67,7 @@ public class JavaEditorFileSwapper extends EditorFileSwapper { if (member != null) { PsiElement navigationElement = member.getNavigationElement(); - if (navigationElement.getContainingFile().getVirtualFile() == sourceFile) { + if (Comparing.equal(navigationElement.getContainingFile().getVirtualFile(), sourceFile)) { position = navigationElement.getTextOffset(); } } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java index 89a0bc7e0443..8b73ad6dd4ca 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java @@ -143,7 +143,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass { myInLibrary = fileIndex.isInLibraryClasses(virtualFile) || fileIndex.isInLibrarySource(virtualFile); myRefCountHolder = RefCountHolder.endUsing(myFile); - if (myRefCountHolder == null || !myRefCountHolder.retrieveUnusedReferencesInfo(new Runnable() { + if (myRefCountHolder == null || !myRefCountHolder.retrieveUnusedReferencesInfo((DaemonProgressIndicator)progress, new Runnable() { @Override public void run() { boolean errorFound = collectHighlights(elementSet, highlights, progress); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java index 6f1260d77dd6..b763e4e6c9a8 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java @@ -47,14 +47,9 @@ public class RefCountHolder { private final Map myDclsUsedMap = new ConcurrentHashMap(); private final Map myImportStatements = new ConcurrentHashMap(); private final Map myPossiblyDuplicateElements = new ConcurrentHashMap(); - private final AtomicReference myState = new AtomicReference(State.VIRGIN); - - private enum State { - VIRGIN, // just created or cleared - BEING_WRITTEN_BY_GHP, // general highlighting pass is storing references during analysis - READY, // may be used for highlighting unused stuff - BEING_USED_BY_PHP, // post highlighting pass is retrieving info - } + private final AtomicReference myState = new AtomicReference(VIRGIN); + private static final DaemonProgressIndicator VIRGIN = new DaemonProgressIndicator(); // just created or cleared + private static final DaemonProgressIndicator READY = new DaemonProgressIndicator(); private static class HolderReference extends SoftReference { @SuppressWarnings("UnusedDeclaration") @@ -122,20 +117,19 @@ public class RefCountHolder { } private void clear() { - assertIsAnalyzing(); - myLocalRefsMap.clear(); + synchronized (myLocalRefsMap) { + myLocalRefsMap.clear(); + } myImportStatements.clear(); myDclsUsedMap.clear(); myPossiblyDuplicateElements.clear(); } public void registerLocallyReferenced(@NotNull PsiNamedElement result) { - assertIsAnalyzing(); myDclsUsedMap.put(result,Boolean.TRUE); } public void registerReference(@NotNull PsiJavaReference ref, @NotNull JavaResolveResult resolveResult) { - assertIsAnalyzing(); PsiElement refElement = resolveResult.getElement(); PsiFile psiFile = refElement == null ? null : refElement.getContainingFile(); if (psiFile != null) psiFile = (PsiFile)psiFile.getNavigationElement(); // look at navigation elements because all references resolve into Cls elements when highlighting library source @@ -154,7 +148,6 @@ public class RefCountHolder { } public boolean isRedundant(@NotNull PsiImportStatementBase importStatement) { - assertIsRetrieving(); return !myImportStatements.containsValue(importStatement); } @@ -167,7 +160,6 @@ public class RefCountHolder { } private void removeInvalidRefs() { - assertIsAnalyzing(); synchronized (myLocalRefsMap) { for(Iterator iterator = myLocalRefsMap.keySet().iterator(); iterator.hasNext();){ PsiReference ref = iterator.next(); @@ -197,8 +189,10 @@ public class RefCountHolder { } public boolean isReferenced(PsiNamedElement element) { - assertIsRetrieving(); - List array = myLocalRefsMap.getKeysByValue(element); + List array; + synchronized (myLocalRefsMap) { + array = myLocalRefsMap.getKeysByValue(element); + } if (array != null && !array.isEmpty() && !isParameterUsedRecursively(element, array)) return true; Boolean usedStatus = myDclsUsedMap.get(element); @@ -235,9 +229,11 @@ public class RefCountHolder { } public boolean isReferencedForRead(@NotNull PsiElement element) { - assertIsRetrieving(); LOG.assertTrue(element instanceof PsiVariable); - List array = myLocalRefsMap.getKeysByValue(element); + List array; + synchronized (myLocalRefsMap) { + array = myLocalRefsMap.getKeysByValue(element); + } if (array == null) return false; for (PsiReference ref : array) { PsiElement refElement = ref.getElement(); @@ -257,9 +253,11 @@ public class RefCountHolder { } public boolean isReferencedForWrite(@NotNull PsiElement element) { - assertIsRetrieving(); LOG.assertTrue(element instanceof PsiVariable); - List array = myLocalRefsMap.getKeysByValue(element); + List array; + synchronized (myLocalRefsMap) { + array = myLocalRefsMap.getKeysByValue(element); + } if (array == null) return false; for (PsiReference ref : array) { final PsiElement refElement = ref.getElement(); @@ -273,14 +271,14 @@ public class RefCountHolder { return false; } - public boolean analyze(@NotNull PsiFile file, TextRange dirtyScope, @NotNull Runnable analyze) { - State old = myState.get(); - myState.compareAndSet(State.READY, State.VIRGIN); - if (!myState.compareAndSet(State.VIRGIN, State.BEING_WRITTEN_BY_GHP)) { - log("a: failed to change " + old + "->" + State.BEING_WRITTEN_BY_GHP); + public boolean analyze(@NotNull PsiFile file, TextRange dirtyScope, @NotNull Runnable analyze, @NotNull DaemonProgressIndicator indicator) { + DaemonProgressIndicator old = myState.get(); + if (old != VIRGIN && old != READY) return false; + if (!myState.compareAndSet(old, indicator)) { + log("a: failed to change " + old + "->" + indicator); return false; } - log("a: changed " + old + "->" + State.BEING_WRITTEN_BY_GHP); + log("a: changed " + old + "->" + indicator); boolean finished = false; try { if (dirtyScope != null) { @@ -296,9 +294,9 @@ public class RefCountHolder { finished = true; } finally { - boolean set = myState.compareAndSet(State.BEING_WRITTEN_BY_GHP, finished ? State.READY : State.VIRGIN); + boolean set = myState.compareAndSet(indicator, finished ? READY : VIRGIN); assert set : myState.get(); - log("a: changed back " + State.BEING_WRITTEN_BY_GHP + "->" + (finished ? State.READY : State.VIRGIN)); + log("a: changed back " + indicator + "->" + (finished ? READY : VIRGIN)); } return true; } @@ -307,31 +305,21 @@ public class RefCountHolder { //System.err.println("RFC: "+s); } - public boolean retrieveUnusedReferencesInfo(@NotNull Runnable analyze) { - State old = myState.get(); - if (!myState.compareAndSet(State.READY, State.BEING_USED_BY_PHP)) { - log("r: failed to change " + old + "->" + State.BEING_USED_BY_PHP); + public boolean retrieveUnusedReferencesInfo(@NotNull DaemonProgressIndicator indicator, @NotNull Runnable analyze) { + DaemonProgressIndicator old = myState.get(); + if (!myState.compareAndSet(READY, indicator)) { + log("r: failed to change " + old + "->" + indicator); return false; } - log("r: changed " + old + "->" + State.BEING_USED_BY_PHP); + log("r: changed " + old + "->" + indicator); try { analyze.run(); } finally { - boolean set = myState.compareAndSet(State.BEING_USED_BY_PHP, State.READY); + boolean set = myState.compareAndSet(indicator, READY); assert set : myState.get(); - log("r: changed back " + State.BEING_USED_BY_PHP + "->" + State.READY); + log("r: changed back " + indicator + "->" + READY); } return true; } - - private void assertIsAnalyzing() { - State state = myState.get(); - assert state == State.BEING_WRITTEN_BY_GHP : state; - } - private void assertIsRetrieving() { - State state = myState.get(); - assert state == State.BEING_USED_BY_PHP : state; - } - } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index e1b1cbed1f8a..6924f7ab438c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -24,6 +24,7 @@ import com.intellij.codeInsight.daemon.impl.quickfix.SetupJDKFix; import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.IndexNotReadyException; @@ -131,7 +132,8 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh myRefCountHolder = refCountHolder; Document document = PsiDocumentManager.getInstance(project).getDocument(file); TextRange dirtyScope = document == null ? file.getTextRange() : fileStatusMap.getFileDirtyScope(document, Pass.UPDATE_ALL); - success = refCountHolder.analyze(file, dirtyScope, action); + ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); + success = indicator instanceof DaemonProgressIndicator && refCountHolder.analyze(file, dirtyScope, action, (DaemonProgressIndicator)indicator); } else { myRefCountHolder = null; diff --git a/java/java-impl/src/com/intellij/ide/favoritesTreeView/PsiClassFavoriteNodeProvider.java b/java/java-impl/src/com/intellij/ide/favoritesTreeView/PsiClassFavoriteNodeProvider.java index 723be0258738..14291be2775d 100644 --- a/java/java-impl/src/com/intellij/ide/favoritesTreeView/PsiClassFavoriteNodeProvider.java +++ b/java/java-impl/src/com/intellij/ide/favoritesTreeView/PsiClassFavoriteNodeProvider.java @@ -31,6 +31,7 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; @@ -77,7 +78,7 @@ public class PsiClassFavoriteNodeProvider extends FavoriteNodeProvider { public boolean elementContainsFile(final Object element, final VirtualFile vFile) { if (element instanceof PsiClass) { final PsiFile file = ((PsiClass)element).getContainingFile(); - if (file != null && file.getVirtualFile() == vFile) return true; + if (file != null && Comparing.equal(file.getVirtualFile(), vFile)) return true; } return false; } diff --git a/java/java-impl/src/com/intellij/openapi/roots/impl/ExcludeCompilerOutputPolicy.java b/java/java-impl/src/com/intellij/openapi/roots/impl/ExcludeCompilerOutputPolicy.java index dca26c3a8b7c..7dfb138567b4 100644 --- a/java/java-impl/src/com/intellij/openapi/roots/impl/ExcludeCompilerOutputPolicy.java +++ b/java/java-impl/src/com/intellij/openapi/roots/impl/ExcludeCompilerOutputPolicy.java @@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.CompilerModuleExtension; import com.intellij.openapi.roots.CompilerProjectExtension; import com.intellij.openapi.roots.ModuleRootModel; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.pointers.VirtualFilePointer; import com.intellij.openapi.util.io.FileUtil; @@ -53,7 +54,8 @@ public class ExcludeCompilerOutputPolicy implements DirectoryIndexExcludePolicy @Override public boolean isExcludeRootForModule(final Module module, final VirtualFile excludeRoot) { final CompilerModuleExtension compilerModuleExtension = CompilerModuleExtension.getInstance(module); - return compilerModuleExtension.getCompilerOutputPath() == excludeRoot || compilerModuleExtension.getCompilerOutputPathForTests() == excludeRoot; + return Comparing.equal(compilerModuleExtension.getCompilerOutputPath(), excludeRoot) || + Comparing.equal(compilerModuleExtension.getCompilerOutputPathForTests(), excludeRoot); } @Override @@ -87,7 +89,7 @@ public class ExcludeCompilerOutputPolicy implements DirectoryIndexExcludePolicy private static boolean isEqualWithFileOrUrl(VirtualFile f, VirtualFile fileToCompareWith, String url) { if (fileToCompareWith != null) { - if (fileToCompareWith == f) return true; + if (Comparing.equal(fileToCompareWith, f)) return true; } else if (url != null) { if (FileUtil.pathsEqual(url, f.getUrl())) return true; diff --git a/java/java-impl/src/com/intellij/packageDependencies/ui/TreeModelBuilder.java b/java/java-impl/src/com/intellij/packageDependencies/ui/TreeModelBuilder.java index cae9eb2b3df5..e11d03a93de4 100644 --- a/java/java-impl/src/com/intellij/packageDependencies/ui/TreeModelBuilder.java +++ b/java/java-impl/src/com/intellij/packageDependencies/ui/TreeModelBuilder.java @@ -26,6 +26,7 @@ import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.libraries.LibraryUtil; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; @@ -172,7 +173,7 @@ public class TreeModelBuilder { VirtualFile dir = null; public boolean processFile(VirtualFile fileOrDir) { if (!fileOrDir.isDirectory()) { - if (lastParent != null && dir != fileOrDir.getParent()) { + if (lastParent != null && !Comparing.equal(dir, fileOrDir.getParent())) { lastParent = null; } lastParent = buildFileNode(fileOrDir, lastParent); diff --git a/java/java-impl/src/com/intellij/refactoring/extractSuperclass/JavaExtractSuperBaseDialog.java b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/JavaExtractSuperBaseDialog.java index 674b6b16fe65..0fdb5959f16c 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractSuperclass/JavaExtractSuperBaseDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/JavaExtractSuperBaseDialog.java @@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.ui.ComponentWithBrowseButton; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Pass; import com.intellij.openapi.vfs.VirtualFile; @@ -111,7 +112,7 @@ public abstract class JavaExtractSuperBaseDialog extends ExtractSuperBaseDialog< final VirtualFile sourceRoot = fileIndex.getSourceRootForFile(sourceFile); if (sourceRoot != null) { for (PsiDirectory dir : directories) { - if (fileIndex.getSourceRootForFile(dir.getVirtualFile()) == sourceRoot) { + if (Comparing.equal(fileIndex.getSourceRootForFile(dir.getVirtualFile()), sourceRoot)) { return dir; } } diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/DestinationFolderComboBox.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/DestinationFolderComboBox.java index 23feeb46c4a0..50c2c5fe1448 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/DestinationFolderComboBox.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/DestinationFolderComboBox.java @@ -15,6 +15,8 @@ */ package com.intellij.refactoring.move.moveClassesOrPackages; +import com.intellij.openapi.util.Comparing; +import com.intellij.ui.ListCellRendererWrapper; import com.intellij.ide.util.DirectoryChooser; import com.intellij.openapi.editor.event.DocumentAdapter; import com.intellij.openapi.editor.event.DocumentEvent; @@ -122,7 +124,7 @@ public abstract class DestinationFolderComboBox extends ComboboxWithBrowseButton final ComboBoxModel model = getComboBox().getModel(); for (int i = 0; i < model.getSize(); i++) { DirectoryChooser.ItemWrapper item = (DirectoryChooser.ItemWrapper)model.getElementAt(i); - if (item != NULL_WRAPPER && fileIndex.getSourceRootForFile(item.getDirectory().getVirtualFile()) == root) { + if (item != NULL_WRAPPER && Comparing.equal(fileIndex.getSourceRootForFile(item.getDirectory().getVirtualFile()), root)) { getComboBox().setSelectedItem(item); getComboBox().repaint(); return; @@ -164,7 +166,9 @@ public abstract class DestinationFolderComboBox extends ComboboxWithBrowseButton } final PsiDirectory selectedPsiDirectory = selectedItem.getDirectory(); VirtualFile selectedDestination = selectedPsiDirectory.getVirtualFile(); - if (showChooserWhenDefault && selectedDestination == myInitialTargetDirectory.getVirtualFile() && mySourceRoots.length > 1) { + if (showChooserWhenDefault && + Comparing.equal(selectedDestination, myInitialTargetDirectory.getVirtualFile()) && + mySourceRoots.length > 1) { selectedDestination = MoveClassesOrPackagesUtil.chooseSourceRoot(targetPackage, mySourceRoots, myInitialTargetDirectory); } if (selectedDestination == null) return null; @@ -211,9 +215,10 @@ public abstract class DestinationFolderComboBox extends ComboboxWithBrowseButton DirectoryChooser.ItemWrapper itemWrapper = new DirectoryChooser.ItemWrapper(targetDirectory, pathsToCreate.get(targetDirectory)); items.add(itemWrapper); final VirtualFile sourceRootForFile = fileIndex.getSourceRootForFile(targetDirectory.getVirtualFile()); - if (sourceRootForFile == initialTargetDirectorySourceRoot) { + if (Comparing.equal(sourceRootForFile, initialTargetDirectorySourceRoot)) { initial = itemWrapper; - } else if (sourceRootForFile == oldSelection) { + } + else if (Comparing.equal(sourceRootForFile, oldSelection)) { oldOne = itemWrapper; } } diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java index 1d4afb77e665..901cac555ffb 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java @@ -205,7 +205,7 @@ public class MoveInnerDialog extends RefactoringDialog { final PsiDirectory[] directories = oldPackage.getDirectories(); final VirtualFile root = projectRootManager.getFileIndex().getContentRootForFile(psiDirectory.getVirtualFile()); for(PsiDirectory dir: directories) { - if (projectRootManager.getFileIndex().getContentRootForFile(dir.getVirtualFile()) == root) { + if (Comparing.equal(projectRootManager.getFileIndex().getContentRootForFile(dir.getVirtualFile()), root)) { initialDir = dir; } } diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaFileManagerBase.java b/java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaFileManagerBase.java index 3bb06f50eee1..2c4e64e36ff8 100644 --- a/java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaFileManagerBase.java +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaFileManagerBase.java @@ -20,6 +20,7 @@ import com.intellij.ide.highlighter.JavaClassFileType; import com.intellij.openapi.Disposable; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.roots.*; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; @@ -314,7 +315,7 @@ public abstract class JavaFileManagerBase implements JavaFileManager, Disposable final VirtualFile root = ProjectRootManager.getInstance(myManager.getProject()).getFileIndex().getClassRootForFile(vFile); VirtualFile parent = vFile.getParent(); final PsiNameHelper nameHelper = JavaPsiFacade.getInstance(myManager.getProject()).getNameHelper(); - while (parent != null && parent != root) { + while (parent != null && !Comparing.equal(parent, root)) { if (!nameHelper.isIdentifier(parent.getName())) return false; parent = parent.getParent(); } @@ -332,7 +333,7 @@ public abstract class JavaFileManagerBase implements JavaFileManager, Disposable final ProjectFileIndex fileIndex = rootManager.getFileIndex(); for (final VirtualFile sourceRoot : sourceRoots) { final String packageName = fileIndex.getPackageNameByDirectory(sourceRoot); - if (packageName != null && packageName.length() > 0) { + if (packageName != null && !packageName.isEmpty()) { names.add(packageName); } } diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java index b88ac9e77309..049c6feb304b 100644 --- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java @@ -1,9 +1,25 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.psi.impl.search; import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.progress.ProgressIndicatorProvider; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -179,7 +195,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor guessFromContent(VirtualFile virtualFile, byte[] content, int length) { + public static Trinity guessFromContent(VirtualFile virtualFile, byte[] content, int length) { EncodingRegistry settings = EncodingRegistry.getInstance(); boolean shouldGuess = settings != null && settings.isUseUTFGuessing(virtualFile); CharsetToolkit toolkit = shouldGuess ? new CharsetToolkit(content, EncodingRegistry.getInstance().getDefaultCharset()) : null; diff --git a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/JdkScope.java b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/JdkScope.java index 0e613662a573..a34f18259b57 100644 --- a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/JdkScope.java +++ b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/JdkScope.java @@ -22,6 +22,7 @@ import com.intellij.openapi.roots.JdkOrderEntry; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.containers.ContainerUtil; @@ -74,8 +75,8 @@ public class JdkScope extends GlobalSearchScope { final VirtualFile r1 = getFileRoot(file1); final VirtualFile r2 = getFileRoot(file2); for (VirtualFile root : myEntries) { - if (r1 == root) return 1; - if (r2 == root) return -1; + if (Comparing.equal(r1, root)) return 1; + if (Comparing.equal(r2, root)) return -1; } return 0; } diff --git a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/LibraryRuntimeClasspathScope.java b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/LibraryRuntimeClasspathScope.java index dfa53f3245ba..4e77639ad6fb 100644 --- a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/LibraryRuntimeClasspathScope.java +++ b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/LibraryRuntimeClasspathScope.java @@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.search.GlobalSearchScope; @@ -144,8 +145,8 @@ public class LibraryRuntimeClasspathScope extends GlobalSearchScope { final VirtualFile r1 = getFileRoot(file1); final VirtualFile r2 = getFileRoot(file2); for (VirtualFile root : myEntries) { - if (r1 == root) return 1; - if (r2 == root) return -1; + if (Comparing.equal(r1, root)) return 1; + if (Comparing.equal(r2, root)) return -1; } return 0; } diff --git a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java index bd97a36bb5e8..ed52ba95b6b8 100644 --- a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java +++ b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java @@ -17,6 +17,7 @@ package com.intellij.openapi.module.impl.scopes; import com.intellij.openapi.module.Module; import com.intellij.openapi.roots.*; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiBundle; import com.intellij.psi.search.GlobalSearchScope; @@ -147,14 +148,14 @@ public class ModuleWithDependenciesScope extends GlobalSearchScope { public int compare(VirtualFile file1, VirtualFile file2) { VirtualFile r1 = getFileRoot(file1); VirtualFile r2 = getFileRoot(file2); - if (r1 == r2) return 0; + if (Comparing.equal(r1, r2)) return 0; if (r1 == null) return -1; if (r2 == null) return 1; for (VirtualFile root : myRoots) { - if (r1 == root) return 1; - if (r2 == root) return -1; + if (Comparing.equal(r1, root)) return 1; + if (Comparing.equal(r2, root)) return -1; } return 0; } diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java b/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java index 102d132e8193..bcb5e0b89808 100644 --- a/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java +++ b/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java @@ -26,10 +26,7 @@ import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressIndicatorProvider; import com.intellij.openapi.roots.FileIndexFacade; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.Condition; -import com.intellij.openapi.util.NullableComputable; -import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; @@ -767,7 +764,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { @Override public boolean process(VirtualFile file) { - if (file == fileToIgnoreOccurencesInVirtualFile) return true; + if (Comparing.equal(file, fileToIgnoreOccurencesInVirtualFile)) return true; if (!index.shouldBeFound(scope, file)) return true; final int value = count.incrementAndGet(); return value < 10; diff --git a/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementWeigher.java b/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementWeigher.java index fff9c3bf551d..61df4cd82467 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementWeigher.java +++ b/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementWeigher.java @@ -16,15 +16,26 @@ package com.intellij.codeInsight.lookup; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author peter */ public abstract class LookupElementWeigher { private final String myId; + private final boolean myNegated; + + protected LookupElementWeigher(String id, boolean negated) { + myId = id; + myNegated = negated; + } protected LookupElementWeigher(String id) { - myId = id; + this(id, false); + } + + public boolean isNegated() { + return myNegated; } @Override @@ -32,7 +43,7 @@ public abstract class LookupElementWeigher { return myId; } - @NotNull + @Nullable public abstract Comparable weigh(@NotNull LookupElement element); } diff --git a/platform/lang-api/src/com/intellij/ide/projectView/ProjectViewNode.java b/platform/lang-api/src/com/intellij/ide/projectView/ProjectViewNode.java index f3aec40ed66c..355ee56803d9 100644 --- a/platform/lang-api/src/com/intellij/ide/projectView/ProjectViewNode.java +++ b/platform/lang-api/src/com/intellij/ide/projectView/ProjectViewNode.java @@ -18,6 +18,7 @@ package com.intellij.ide.projectView; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.VfsUtil; @@ -189,7 +190,7 @@ public abstract class ProjectViewNode extends AbstractTreeNode im public boolean value(final VirtualFile virtualFile) { return contains(virtualFile) // in case of flattened packages, when package node a.b.c contains error file, node a.b might not. - && (getValue() instanceof PsiElement && PsiUtilBase.getVirtualFile((PsiElement)getValue()) == virtualFile || + && (getValue() instanceof PsiElement && Comparing.equal(PsiUtilBase.getVirtualFile((PsiElement)getValue()), virtualFile) || someChildContainsFile(virtualFile)); } }); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java index 643422517170..fe911cdde33a 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java @@ -1,371 +1,372 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.intellij.codeInsight.completion; - -import com.intellij.codeInsight.CodeInsightBundle; -import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.codeInsight.lookup.LookupElementPresentation; -import com.intellij.navigation.ChooseByNameContributor; -import com.intellij.openapi.actionSystem.IdeActions; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.fileTypes.FileNameMatcher; -import com.intellij.openapi.fileTypes.FileType; -import com.intellij.openapi.fileTypes.FileTypeManager; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.progress.ProcessCanceledException; -import com.intellij.openapi.progress.ProgressManager; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.ProjectFileIndex; -import com.intellij.openapi.roots.ProjectRootManager; -import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiFileSystemItem; -import com.intellij.psi.PsiReference; -import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference; -import com.intellij.psi.impl.source.resolve.reference.impl.providers.*; -import com.intellij.psi.search.FilenameIndex; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.search.ProjectScope; -import com.intellij.util.ArrayUtil; -import com.intellij.util.ProcessingContext; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; -import java.util.*; - -import static com.intellij.patterns.PlatformPatterns.psiElement; - -/** - * @author spleaner - */ -public class FilePathCompletionContributor extends CompletionContributor { - private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.FilePathCompletionContributor"); - - public FilePathCompletionContributor() { - extend(CompletionType.BASIC, psiElement(), new CompletionProvider() { - @Override - protected void addCompletions(@NotNull CompletionParameters parameters, - ProcessingContext context, - @NotNull CompletionResultSet result) { - final PsiReference psiReference = parameters.getPosition().getContainingFile().findReferenceAt(parameters.getOffset()); - if (getReference(psiReference) != null && parameters.getInvocationCount() == 1) { - final String shortcut = getActionShortcut(IdeActions.ACTION_CODE_COMPLETION); - if (shortcut != null) { - CompletionService.getCompletionService().setAdvertisementText(CodeInsightBundle.message("class.completion.file.path", shortcut)); - } - } - } - }); - - CompletionProvider provider = new CompletionProvider() { - @Override - protected void addCompletions(@NotNull final CompletionParameters parameters, - ProcessingContext context, - @NotNull final CompletionResultSet _result) { - if (!parameters.isExtendedCompletion()) { - return; - } - - @NotNull final CompletionResultSet result = _result.caseInsensitive(); - final PsiElement e = parameters.getPosition(); - final Project project = e.getProject(); - - final PsiReference psiReference = parameters.getPosition().getContainingFile().findReferenceAt(parameters.getOffset()); - - final Pair fileReferencePair = getReference(psiReference); - if (fileReferencePair != null) { - final FileReference first = fileReferencePair.getFirst(); - if (first == null) return; - - final FileReferenceSet set = first.getFileReferenceSet(); - String prefix = set.getPathString() - .substring(0, parameters.getOffset() - set.getElement().getTextRange().getStartOffset() - set.getStartInElement()); - final String textBeforePosition = e.getContainingFile().getText().substring(0, parameters.getOffset()); - if (!textBeforePosition.endsWith(prefix)) { - final int len = textBeforePosition.length(); - final String fragment = len > 100 ? textBeforePosition.substring(len - 100) : textBeforePosition; - throw new AssertionError("prefix should be some actual file string just before caret: " + - prefix + - "\n text=" + - fragment + - ";\npathString=" + - set.getPathString() + - ";\nelementText=" + - e.getParent().getText()); - } - - List pathPrefixParts = null; - int lastSlashIndex; - if ((lastSlashIndex = prefix.lastIndexOf('/')) != -1) { - pathPrefixParts = StringUtil.split(prefix.substring(0, lastSlashIndex), "/"); - prefix = prefix.substring(lastSlashIndex + 1); - } - - final CompletionResultSet __result = result.withPrefixMatcher(prefix).caseInsensitive(); - - final PsiFile originalFile = parameters.getOriginalFile(); - final VirtualFile contextFile = originalFile.getVirtualFile(); - if (contextFile != null) { - final String[] fileNames = getAllNames(project); - final Set resultNames = new TreeSet(); - for (String fileName : fileNames) { - if (filenameMatchesPrefixOrType(fileName, prefix, set.getSuitableFileTypes(), parameters.getInvocationCount())) { - resultNames.add(fileName); - } - } - - final ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex(); - - final Module contextModule = index.getModuleForFile(contextFile); - if (contextModule != null) { - final FileReferenceHelper contextHelper = FileReferenceHelperRegistrar.getNotNullHelper(originalFile); - - final GlobalSearchScope scope = ProjectScope.getProjectScope(project); - for (final String name : resultNames) { - ProgressManager.checkCanceled(); - - final PsiFile[] files = FilenameIndex.getFilesByName(project, name, scope); - - if (files.length > 0) { - for (final PsiFile file : files) { - ProgressManager.checkCanceled(); - - final VirtualFile virtualFile = file.getVirtualFile(); - if (virtualFile != null && virtualFile.isValid() && virtualFile != contextFile) { - if (contextHelper.isMine(project, virtualFile)) { - if (pathPrefixParts == null || - fileMatchesPathPrefix(contextHelper.getPsiFileSystemItem(project, virtualFile), pathPrefixParts)) { - __result.addElement(new FilePathLookupItem(file, contextHelper)); - } - } - } - } - } - } - } - } - - if (set.getSuitableFileTypes().length > 0 && parameters.getInvocationCount() == 1) { - final String shortcut = getActionShortcut(IdeActions.ACTION_CODE_COMPLETION); - if (shortcut != null) { - CompletionService.getCompletionService() - .setAdvertisementText(CodeInsightBundle.message("class.completion.file.path.all.variants", shortcut)); - } - } - - if (fileReferencePair.getSecond()) result.stopHere(); - } - } - }; - extend(CompletionType.BASIC, psiElement(), provider); - } - - private static boolean filenameMatchesPrefixOrType(final String fileName, final String prefix, final FileType[] suitableFileTypes, final int invocationCount) { - final boolean prefixMatched = prefix.length() == 0 || StringUtil.startsWithIgnoreCase(fileName, prefix); - if (prefixMatched && (suitableFileTypes.length == 0 || invocationCount > 2)) return true; - - if (prefixMatched) { - final String extension = FileUtil.getExtension(fileName); - if (extension.length() == 0) return false; - - for (final FileType fileType : suitableFileTypes) { - final List matchers = FileTypeManager.getInstance().getAssociations(fileType); - for (final FileNameMatcher matcher : matchers) { - if (matcher.accept(fileName)) return true; - } - } - } - - return false; - } - - private static boolean fileMatchesPathPrefix(@Nullable final PsiFileSystemItem file, @NotNull final List pathPrefix) { - if (file == null) return false; - - final List contextParts = new ArrayList(); - PsiFileSystemItem parentFile = file; - PsiFileSystemItem parent; - while ((parent = parentFile.getParent()) != null) { - if (parent.getName().length() > 0) contextParts.add(0, parent.getName().toLowerCase()); - parentFile = parent; - } - - final String path = StringUtil.join(contextParts, "/"); - - int nextIndex = 0; - for (final String s : pathPrefix) { - if ((nextIndex = path.indexOf(s.toLowerCase(), nextIndex)) == -1) return false; - } - - return true; - } - - private static String[] getAllNames(@NotNull final Project project) { - Set names = new HashSet(); - final ChooseByNameContributor[] nameContributors = ChooseByNameContributor.FILE_EP_NAME.getExtensions(); - for (final ChooseByNameContributor contributor : nameContributors) { - try { - names.addAll(Arrays.asList(contributor.getNames(project, false))); - } - catch (ProcessCanceledException ex) { - // index corruption detected, ignore - } - catch (Exception ex) { - LOG.error(ex); - } - } - - return ArrayUtil.toStringArray(names); - } - - @Nullable - private static Pair getReference(final PsiReference original) { - if (original == null) { - return null; - } - - if (original instanceof PsiMultiReference) { - final PsiMultiReference multiReference = (PsiMultiReference)original; - for (PsiReference reference : multiReference.getReferences()) { - if (reference instanceof FileReference) { - return Pair.create((FileReference) reference, false); - } - } - } - else if (original instanceof FileReferenceOwner) { - final FileReference fileReference = ((FileReferenceOwner)original).getLastFileReference(); - if (fileReference != null) { - return Pair.create(fileReference, true); - } - } - - return null; - } - - public class FilePathLookupItem extends LookupElement { - private final String myName; - private final String myPath; - private final String myInfo; - private final Icon myIcon; - private final PsiFile myFile; - private final FileReferenceHelper myReferenceHelper; - - public FilePathLookupItem(@NotNull final PsiFile file, @NotNull final FileReferenceHelper referenceHelper) { - myName = file.getName(); - myPath = file.getVirtualFile().getPath(); - - myReferenceHelper = referenceHelper; - - myInfo = FileInfoManager.getFileAdditionalInfo(file); - myIcon = file.getFileType().getIcon(); - - myFile = file; - } - - @SuppressWarnings({"HardCodedStringLiteral"}) - @Override - public String toString() { - return String.format("%s%s", myName, myInfo == null ? "" : " (" + myInfo + ")"); - } - - @NotNull - @Override - public Object getObject() { - return myFile; - } - - @NotNull - public String getLookupString() { - return myName; - } - - @Override - public void handleInsert(InsertionContext context) { - context.commitDocument(); - if (myFile.isValid()) { - final PsiReference psiReference = context.getFile().findReferenceAt(context.getStartOffset()); - final Pair fileReferencePair = getReference(psiReference); - LOG.assertTrue(fileReferencePair != null); - - FileReference ref = fileReferencePair.getFirst(); - context.setTailOffset(ref.getRangeInElement().getEndOffset() + ref.getElement().getTextRange().getStartOffset()); - ref.bindToElement(myFile, true); - } - } - - @Override - public void renderElement(LookupElementPresentation presentation) { - final VirtualFile virtualFile = myFile.getVirtualFile(); - LOG.assertTrue(virtualFile != null); - final PsiFileSystemItem root = myReferenceHelper.findRoot(myFile.getProject(), virtualFile); - final String relativePath = PsiFileSystemItemUtil.getRelativePath(root, myReferenceHelper.getPsiFileSystemItem(myFile.getProject(), virtualFile)); - - final StringBuilder sb = new StringBuilder(); - if (myInfo != null) { - sb.append(" (").append(myInfo); - } - - if (relativePath != null && !relativePath.equals(myName)) { - if (myInfo != null) { - sb.append(", "); - } - else { - sb.append(" ("); - } - - sb.append(relativePath); - } - - if (sb.length() > 0) { - sb.append(')'); - } - - presentation.setItemText(myName); - - if (sb.length() > 0) { - presentation.setTailText(sb.toString(), true); - } - - presentation.setIcon(myIcon); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - FilePathLookupItem that = (FilePathLookupItem)o; - - if (!myName.equals(that.myName)) return false; - if (!myPath.equals(that.myPath)) return false; - - return true; - } - - @Override - public int hashCode() { - int result = myName.hashCode(); - result = 31 * result + myPath.hashCode(); - return result; - } - } -} +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intellij.codeInsight.completion; + +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementPresentation; +import com.intellij.navigation.ChooseByNameContributor; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileNameMatcher; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiFileSystemItem; +import com.intellij.psi.PsiReference; +import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference; +import com.intellij.psi.impl.source.resolve.reference.impl.providers.*; +import com.intellij.psi.search.FilenameIndex; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.ProjectScope; +import com.intellij.util.ArrayUtil; +import com.intellij.util.ProcessingContext; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.*; + +import static com.intellij.patterns.PlatformPatterns.psiElement; + +/** + * @author spleaner + */ +public class FilePathCompletionContributor extends CompletionContributor { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.FilePathCompletionContributor"); + + public FilePathCompletionContributor() { + extend(CompletionType.BASIC, psiElement(), new CompletionProvider() { + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet result) { + final PsiReference psiReference = parameters.getPosition().getContainingFile().findReferenceAt(parameters.getOffset()); + if (getReference(psiReference) != null && parameters.getInvocationCount() == 1) { + final String shortcut = getActionShortcut(IdeActions.ACTION_CODE_COMPLETION); + if (shortcut != null) { + CompletionService.getCompletionService().setAdvertisementText(CodeInsightBundle.message("class.completion.file.path", shortcut)); + } + } + } + }); + + CompletionProvider provider = new CompletionProvider() { + @Override + protected void addCompletions(@NotNull final CompletionParameters parameters, + ProcessingContext context, + @NotNull final CompletionResultSet _result) { + if (!parameters.isExtendedCompletion()) { + return; + } + + @NotNull final CompletionResultSet result = _result.caseInsensitive(); + final PsiElement e = parameters.getPosition(); + final Project project = e.getProject(); + + final PsiReference psiReference = parameters.getPosition().getContainingFile().findReferenceAt(parameters.getOffset()); + + final Pair fileReferencePair = getReference(psiReference); + if (fileReferencePair != null) { + final FileReference first = fileReferencePair.getFirst(); + if (first == null) return; + + final FileReferenceSet set = first.getFileReferenceSet(); + String prefix = set.getPathString() + .substring(0, parameters.getOffset() - set.getElement().getTextRange().getStartOffset() - set.getStartInElement()); + final String textBeforePosition = e.getContainingFile().getText().substring(0, parameters.getOffset()); + if (!textBeforePosition.endsWith(prefix)) { + final int len = textBeforePosition.length(); + final String fragment = len > 100 ? textBeforePosition.substring(len - 100) : textBeforePosition; + throw new AssertionError("prefix should be some actual file string just before caret: " + + prefix + + "\n text=" + + fragment + + ";\npathString=" + + set.getPathString() + + ";\nelementText=" + + e.getParent().getText()); + } + + List pathPrefixParts = null; + int lastSlashIndex; + if ((lastSlashIndex = prefix.lastIndexOf('/')) != -1) { + pathPrefixParts = StringUtil.split(prefix.substring(0, lastSlashIndex), "/"); + prefix = prefix.substring(lastSlashIndex + 1); + } + + final CompletionResultSet __result = result.withPrefixMatcher(prefix).caseInsensitive(); + + final PsiFile originalFile = parameters.getOriginalFile(); + final VirtualFile contextFile = originalFile.getVirtualFile(); + if (contextFile != null) { + final String[] fileNames = getAllNames(project); + final Set resultNames = new TreeSet(); + for (String fileName : fileNames) { + if (filenameMatchesPrefixOrType(fileName, prefix, set.getSuitableFileTypes(), parameters.getInvocationCount())) { + resultNames.add(fileName); + } + } + + final ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex(); + + final Module contextModule = index.getModuleForFile(contextFile); + if (contextModule != null) { + final FileReferenceHelper contextHelper = FileReferenceHelperRegistrar.getNotNullHelper(originalFile); + + final GlobalSearchScope scope = ProjectScope.getProjectScope(project); + for (final String name : resultNames) { + ProgressManager.checkCanceled(); + + final PsiFile[] files = FilenameIndex.getFilesByName(project, name, scope); + + if (files.length > 0) { + for (final PsiFile file : files) { + ProgressManager.checkCanceled(); + + final VirtualFile virtualFile = file.getVirtualFile(); + if (virtualFile != null && virtualFile.isValid() && !Comparing.equal(virtualFile, contextFile)) { + if (contextHelper.isMine(project, virtualFile)) { + if (pathPrefixParts == null || + fileMatchesPathPrefix(contextHelper.getPsiFileSystemItem(project, virtualFile), pathPrefixParts)) { + __result.addElement(new FilePathLookupItem(file, contextHelper)); + } + } + } + } + } + } + } + } + + if (set.getSuitableFileTypes().length > 0 && parameters.getInvocationCount() == 1) { + final String shortcut = getActionShortcut(IdeActions.ACTION_CODE_COMPLETION); + if (shortcut != null) { + CompletionService.getCompletionService() + .setAdvertisementText(CodeInsightBundle.message("class.completion.file.path.all.variants", shortcut)); + } + } + + if (fileReferencePair.getSecond()) result.stopHere(); + } + } + }; + extend(CompletionType.BASIC, psiElement(), provider); + } + + private static boolean filenameMatchesPrefixOrType(final String fileName, final String prefix, final FileType[] suitableFileTypes, final int invocationCount) { + final boolean prefixMatched = prefix.length() == 0 || StringUtil.startsWithIgnoreCase(fileName, prefix); + if (prefixMatched && (suitableFileTypes.length == 0 || invocationCount > 2)) return true; + + if (prefixMatched) { + final String extension = FileUtil.getExtension(fileName); + if (extension.length() == 0) return false; + + for (final FileType fileType : suitableFileTypes) { + final List matchers = FileTypeManager.getInstance().getAssociations(fileType); + for (final FileNameMatcher matcher : matchers) { + if (matcher.accept(fileName)) return true; + } + } + } + + return false; + } + + private static boolean fileMatchesPathPrefix(@Nullable final PsiFileSystemItem file, @NotNull final List pathPrefix) { + if (file == null) return false; + + final List contextParts = new ArrayList(); + PsiFileSystemItem parentFile = file; + PsiFileSystemItem parent; + while ((parent = parentFile.getParent()) != null) { + if (parent.getName().length() > 0) contextParts.add(0, parent.getName().toLowerCase()); + parentFile = parent; + } + + final String path = StringUtil.join(contextParts, "/"); + + int nextIndex = 0; + for (final String s : pathPrefix) { + if ((nextIndex = path.indexOf(s.toLowerCase(), nextIndex)) == -1) return false; + } + + return true; + } + + private static String[] getAllNames(@NotNull final Project project) { + Set names = new HashSet(); + final ChooseByNameContributor[] nameContributors = ChooseByNameContributor.FILE_EP_NAME.getExtensions(); + for (final ChooseByNameContributor contributor : nameContributors) { + try { + names.addAll(Arrays.asList(contributor.getNames(project, false))); + } + catch (ProcessCanceledException ex) { + // index corruption detected, ignore + } + catch (Exception ex) { + LOG.error(ex); + } + } + + return ArrayUtil.toStringArray(names); + } + + @Nullable + private static Pair getReference(final PsiReference original) { + if (original == null) { + return null; + } + + if (original instanceof PsiMultiReference) { + final PsiMultiReference multiReference = (PsiMultiReference)original; + for (PsiReference reference : multiReference.getReferences()) { + if (reference instanceof FileReference) { + return Pair.create((FileReference) reference, false); + } + } + } + else if (original instanceof FileReferenceOwner) { + final FileReference fileReference = ((FileReferenceOwner)original).getLastFileReference(); + if (fileReference != null) { + return Pair.create(fileReference, true); + } + } + + return null; + } + + public class FilePathLookupItem extends LookupElement { + private final String myName; + private final String myPath; + private final String myInfo; + private final Icon myIcon; + private final PsiFile myFile; + private final FileReferenceHelper myReferenceHelper; + + public FilePathLookupItem(@NotNull final PsiFile file, @NotNull final FileReferenceHelper referenceHelper) { + myName = file.getName(); + myPath = file.getVirtualFile().getPath(); + + myReferenceHelper = referenceHelper; + + myInfo = FileInfoManager.getFileAdditionalInfo(file); + myIcon = file.getFileType().getIcon(); + + myFile = file; + } + + @SuppressWarnings({"HardCodedStringLiteral"}) + @Override + public String toString() { + return String.format("%s%s", myName, myInfo == null ? "" : " (" + myInfo + ")"); + } + + @NotNull + @Override + public Object getObject() { + return myFile; + } + + @NotNull + public String getLookupString() { + return myName; + } + + @Override + public void handleInsert(InsertionContext context) { + context.commitDocument(); + if (myFile.isValid()) { + final PsiReference psiReference = context.getFile().findReferenceAt(context.getStartOffset()); + final Pair fileReferencePair = getReference(psiReference); + LOG.assertTrue(fileReferencePair != null); + + FileReference ref = fileReferencePair.getFirst(); + context.setTailOffset(ref.getRangeInElement().getEndOffset() + ref.getElement().getTextRange().getStartOffset()); + ref.bindToElement(myFile, true); + } + } + + @Override + public void renderElement(LookupElementPresentation presentation) { + final VirtualFile virtualFile = myFile.getVirtualFile(); + LOG.assertTrue(virtualFile != null); + final PsiFileSystemItem root = myReferenceHelper.findRoot(myFile.getProject(), virtualFile); + final String relativePath = PsiFileSystemItemUtil.getRelativePath(root, myReferenceHelper.getPsiFileSystemItem(myFile.getProject(), virtualFile)); + + final StringBuilder sb = new StringBuilder(); + if (myInfo != null) { + sb.append(" (").append(myInfo); + } + + if (relativePath != null && !relativePath.equals(myName)) { + if (myInfo != null) { + sb.append(", "); + } + else { + sb.append(" ("); + } + + sb.append(relativePath); + } + + if (sb.length() > 0) { + sb.append(')'); + } + + presentation.setItemText(myName); + + if (sb.length() > 0) { + presentation.setTailText(sb.toString(), true); + } + + presentation.setIcon(myIcon); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + FilePathLookupItem that = (FilePathLookupItem)o; + + if (!myName.equals(that.myName)) return false; + if (!myPath.equals(that.myPath)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = myName.hashCode(); + result = 31 * result + myPath.hashCode(); + return result; + } + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java index b05af5f6371e..e35d45803640 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java @@ -1,356 +1,355 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.codeInsight.completion.impl; - -import com.intellij.codeInsight.CodeInsightSettings; -import com.intellij.codeInsight.completion.*; -import com.intellij.codeInsight.lookup.*; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.progress.ProgressManager; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectManager; -import com.intellij.openapi.project.ProjectManagerAdapter; -import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.Pair; -import com.intellij.patterns.ElementPattern; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.Weigher; -import com.intellij.psi.WeighingService; -import com.intellij.psi.codeStyle.MinusculeMatcher; -import com.intellij.psi.codeStyle.NameUtil; -import com.intellij.psi.impl.DebugUtil; -import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; -import com.intellij.util.Consumer; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; - -/** - * @author peter - */ -public class CompletionServiceImpl extends CompletionService{ - private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.impl.CompletionServiceImpl"); - private static volatile CompletionPhase ourPhase = CompletionPhase.NoCompletion; - private static String ourPhaseTrace; - private static CodeInsightSettings ourSettings = CodeInsightSettings.getInstance(); - - public CompletionServiceImpl() { - ProjectManager.getInstance().addProjectManagerListener(new ProjectManagerAdapter() { - @Override - public void projectClosing(Project project) { - CompletionProgressIndicator indicator = getCurrentCompletion(); - if (indicator != null && indicator.getProject() == project) { - LookupManager.getInstance(indicator.getProject()).hideActiveLookup(); - setCompletionPhase(CompletionPhase.NoCompletion); - } - else if (indicator == null) { - setCompletionPhase(CompletionPhase.NoCompletion); - } - } - }); - } - - @SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass"}) - public static CompletionServiceImpl getCompletionService() { - return (CompletionServiceImpl)CompletionService.getCompletionService(); - } - - @Override - public String getAdvertisementText() { - final CompletionProgressIndicator completion = getCompletionService().getCurrentCompletion(); - return completion == null ? null : completion.getLookup().getAdvertisementText(); - } - - public void setAdvertisementText(@Nullable final String text) { - final CompletionProgressIndicator completion = getCompletionService().getCurrentCompletion(); - if (completion != null) { - completion.getLookup().setAdvertisementText(text); - } - } - - public CompletionResultSet createResultSet(final CompletionParameters parameters, final Consumer consumer, - @NotNull final CompletionContributor contributor) { - final PsiElement position = parameters.getPosition(); - final String prefix = CompletionData.findPrefixStatic(position, parameters.getOffset()); - final String textBeforePosition = parameters.getPosition().getContainingFile().getText().substring(0, parameters.getOffset()); - ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); - if (!(indicator instanceof CompletionProgressIndicator)) { - throw new AssertionError("createResultSet may be invoked only from completion thread: " + indicator + "!=" + getCurrentCompletion() + "; phase set at " + ourPhaseTrace); - } - CompletionProgressIndicator process = (CompletionProgressIndicator)indicator; - CamelHumpMatcher matcher = new CamelHumpMatcher(prefix); - CompletionSorterImpl sorter = defaultSorter(parameters, matcher); - return new CompletionResultSetImpl(consumer, textBeforePosition, matcher, contributor,parameters, sorter, process, null); - } - - @Override - public CompletionProgressIndicator getCurrentCompletion() { - if (isPhase(CompletionPhase.BgCalculation.class, CompletionPhase.ItemsCalculated.class, CompletionPhase.CommittingDocuments.class, - CompletionPhase.Synchronous.class)) { - return ourPhase.indicator; - } - return null; - } - - private static int getPrefixMatchingDegree(LookupElement item, CompletionLocation location) { - final MinusculeMatcher matcher = getMinusculeMatcher(location.getCompletionParameters().getLookup().itemPattern(item)); - - int max = Integer.MIN_VALUE; - for (String lookupString : item.getAllLookupStrings()) { - max = Math.max(max, matcher.matchingDegree(lookupString)); - } - return max; - } - - private static volatile Pair lastMatcher; - - private static MinusculeMatcher getMinusculeMatcher(String prefix) { - final int setting = ourSettings.COMPLETION_CASE_SENSITIVE; - final NameUtil.MatchingCaseSensitivity sensitivity = - setting == CodeInsightSettings.NONE ? NameUtil.MatchingCaseSensitivity.NONE : - setting == CodeInsightSettings.FIRST_LETTER ? NameUtil.MatchingCaseSensitivity.FIRST_LETTER : NameUtil.MatchingCaseSensitivity.ALL; - - Pair pair = lastMatcher; - if (pair != null && pair.first.equals(prefix)) { - return pair.second; - } - - MinusculeMatcher matcher = new MinusculeMatcher(CamelHumpMatcher.applyMiddleMatching(prefix), sensitivity); - lastMatcher = Pair.create(prefix, matcher); - return matcher; - } - - private static class CompletionResultSetImpl extends CompletionResultSet { - private final String myTextBeforePosition; - private final CompletionParameters myParameters; - private final CompletionSorterImpl mySorter; - private final CompletionProgressIndicator myProcess; - @Nullable private final CompletionResultSetImpl myOriginal; - - public CompletionResultSetImpl(final Consumer consumer, final String textBeforePosition, - final PrefixMatcher prefixMatcher, - CompletionContributor contributor, - CompletionParameters parameters, - @NotNull CompletionSorterImpl sorter, - @NotNull CompletionProgressIndicator process, - @Nullable CompletionResultSetImpl original) { - super(prefixMatcher, consumer, contributor); - myTextBeforePosition = textBeforePosition; - myParameters = parameters; - mySorter = sorter; - myProcess = process; - myOriginal = original; - } - - public void addElement(@NotNull final LookupElement element) { - CompletionResult matched = CompletionResult.wrap(element, getPrefixMatcher(), mySorter); - if (matched != null) { - passResult(matched); - } - } - - @NotNull - public CompletionResultSet withPrefixMatcher(@NotNull final PrefixMatcher matcher) { - if (!myTextBeforePosition.endsWith(matcher.getPrefix())) { - final int len = myTextBeforePosition.length(); - final String fragment = len > 100 ? myTextBeforePosition.substring(len - 100) : myTextBeforePosition; - PsiFile positionFile = myParameters.getPosition().getContainingFile(); - LOG.error("prefix should be some actual file string just before caret: " + matcher.getPrefix() + - "\n text=" + fragment + - "\ninjected=" + (InjectedLanguageUtil.getTopLevelFile(positionFile) != positionFile) + - "\nlang=" + positionFile.getLanguage()); - } - return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, matcher, myContributor, myParameters, mySorter, myProcess, this); - } - - @Override - public void stopHere() { - super.stopHere(); - if (myOriginal != null) { - myOriginal.stopHere(); - } - } - - @NotNull - public CompletionResultSet withPrefixMatcher(@NotNull final String prefix) { - return withPrefixMatcher(new CamelHumpMatcher(prefix)); - } - - @NotNull - @Override - public CompletionResultSet withRelevanceSorter(@NotNull CompletionSorter sorter) { - return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, getPrefixMatcher(), myContributor, myParameters, (CompletionSorterImpl)sorter, myProcess, this); - } - - @NotNull - @Override - public CompletionResultSet caseInsensitive() { - return withPrefixMatcher(new CamelHumpMatcher(getPrefixMatcher().getPrefix(), false)); - } - - @Override - public void restartCompletionOnPrefixChange(ElementPattern prefixCondition) { - final CompletionProgressIndicator indicator = getCompletionService().getCurrentCompletion(); - if (indicator != null) { - indicator.addWatchedPrefix(myTextBeforePosition.length() - getPrefixMatcher().getPrefix().length(), prefixCondition); - } - } - - @Override - public void restartCompletionWhenNothingMatches() { - final CompletionProgressIndicator indicator = getCompletionService().getCurrentCompletion(); - if (indicator != null) { - indicator.getLookup().setStartCompletionWhenNothingMatches(true); - } - } - } - - public static boolean assertPhase(Class... possibilities) { - if (!isPhase(possibilities)) { - LOG.error(ourPhase + "; set at " + ourPhaseTrace); - return false; - } - return true; - } - - public static boolean isPhase(Class... possibilities) { - CompletionPhase phase = getCompletionPhase(); - for (Class possibility : possibilities) { - if (possibility.isInstance(phase)) { - return true; - } - } - return false; - } - - public static void setCompletionPhase(@NotNull CompletionPhase phase) { - ApplicationManager.getApplication().assertIsDispatchThread(); - CompletionPhase oldPhase = getCompletionPhase(); - CompletionProgressIndicator oldIndicator = oldPhase.indicator; - if (oldIndicator != null && !(phase instanceof CompletionPhase.BgCalculation)) { - LOG.assertTrue(!oldIndicator.isRunning() || oldIndicator.isCanceled(), "don't change phase during running completion: oldPhase=" + oldPhase); - } - - Disposer.dispose(oldPhase); - ourPhase = phase; - ourPhaseTrace = DebugUtil.currentStackTrace(); - } - - public static CompletionPhase getCompletionPhase() { -// ApplicationManager.getApplication().assertIsDispatchThread(); - CompletionPhase phase = getPhaseRaw(); - ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); - if (indicator != null) { - indicator.checkCanceled(); - } - return phase; - } - - public static CompletionPhase getPhaseRaw() { - return ourPhase; - } - - public CompletionSorterImpl defaultSorter(CompletionParameters parameters, final PrefixMatcher matcher) { - final CompletionLocation location = new CompletionLocation(parameters); - - CompletionSorterImpl sorter = emptySorter(); - sorter = sorter.withClassifier(new PreferStartMatching(location)); - - for (final Weigher weigher : WeighingService.getWeighers(CompletionService.RELEVANCE_KEY)) { - final String id = weigher.toString(); - if ("prefix".equals(id)) { - sorter = sorter.withClassifier(new PrefixMatchingClassifier(id, location)); - } - else { - sorter = sorter.weigh(new LookupElementWeigher(id) { - @NotNull - @Override - public Comparable weigh(@NotNull LookupElement element) { - return new NegatingComparable(weigher.weigh(element, location)); - } - }); - } - - } - - if (parameters.getCompletionType() == CompletionType.SMART) { - return sorter; - } - - return sorter.withClassifier("priority", true, new ClassifierFactory("liftShorter") { - @Override - public Classifier createClassifier(final Classifier next) { - return new LiftShorterItemsClassifier(next, new LiftShorterItemsClassifier.LiftingCondition()); - } - }); - } - - public CompletionSorterImpl emptySorter() { - return new CompletionSorterImpl(new ArrayList>()); - } - - private static class PreferStartMatching extends ClassifierFactory { - private final CompletionLocation myLocation; - - public PreferStartMatching(CompletionLocation location) { - super("startMatching"); - myLocation = location; - } - - @Override - public Classifier createClassifier(Classifier next) { - return new ComparingClassifier(next, "startMatching") { - @NotNull - @Override - public Comparable getWeight(LookupElement element) { - PrefixMatcher itemMatcher = myLocation.getCompletionParameters().getLookup().itemMatcher(element); - for (String ls : element.getAllLookupStrings()) { - if (itemMatcher.isStartMatch(ls)) { - return false; - } - } - return true; - } - }; - } - } - - private static class PrefixMatchingClassifier extends ClassifierFactory { - private final String myId; - private final CompletionLocation myLocation; - - public PrefixMatchingClassifier(String id, CompletionLocation location) { - super(id); - myId = id; - myLocation = location; - } - - @Override - public Classifier createClassifier(Classifier next) { - return new ComparingClassifier(next, myId) { - @NotNull - @Override - public Comparable getWeight(LookupElement element) { - return -getPrefixMatchingDegree(element, myLocation); - } - }; - } - } -} +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.completion.impl; + +import com.intellij.codeInsight.CodeInsightSettings; +import com.intellij.codeInsight.completion.*; +import com.intellij.codeInsight.lookup.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.project.ProjectManagerAdapter; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Pair; +import com.intellij.patterns.ElementPattern; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.Weigher; +import com.intellij.psi.WeighingService; +import com.intellij.psi.codeStyle.MinusculeMatcher; +import com.intellij.psi.codeStyle.NameUtil; +import com.intellij.psi.impl.DebugUtil; +import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; +import com.intellij.util.Consumer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; + +/** + * @author peter + */ +public class CompletionServiceImpl extends CompletionService{ + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.impl.CompletionServiceImpl"); + private static volatile CompletionPhase ourPhase = CompletionPhase.NoCompletion; + private static String ourPhaseTrace; + private static CodeInsightSettings ourSettings = CodeInsightSettings.getInstance(); + + public CompletionServiceImpl() { + ProjectManager.getInstance().addProjectManagerListener(new ProjectManagerAdapter() { + @Override + public void projectClosing(Project project) { + CompletionProgressIndicator indicator = getCurrentCompletion(); + if (indicator != null && indicator.getProject() == project) { + LookupManager.getInstance(indicator.getProject()).hideActiveLookup(); + setCompletionPhase(CompletionPhase.NoCompletion); + } + else if (indicator == null) { + setCompletionPhase(CompletionPhase.NoCompletion); + } + } + }); + } + + @SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass"}) + public static CompletionServiceImpl getCompletionService() { + return (CompletionServiceImpl)CompletionService.getCompletionService(); + } + + @Override + public String getAdvertisementText() { + final CompletionProgressIndicator completion = getCompletionService().getCurrentCompletion(); + return completion == null ? null : completion.getLookup().getAdvertisementText(); + } + + public void setAdvertisementText(@Nullable final String text) { + final CompletionProgressIndicator completion = getCompletionService().getCurrentCompletion(); + if (completion != null) { + completion.getLookup().setAdvertisementText(text); + } + } + + public CompletionResultSet createResultSet(final CompletionParameters parameters, final Consumer consumer, + @NotNull final CompletionContributor contributor) { + final PsiElement position = parameters.getPosition(); + final String prefix = CompletionData.findPrefixStatic(position, parameters.getOffset()); + final String textBeforePosition = parameters.getPosition().getContainingFile().getText().substring(0, parameters.getOffset()); + ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); + if (!(indicator instanceof CompletionProgressIndicator)) { + throw new AssertionError("createResultSet may be invoked only from completion thread: " + indicator + "!=" + getCurrentCompletion() + "; phase set at " + ourPhaseTrace); + } + CompletionProgressIndicator process = (CompletionProgressIndicator)indicator; + CamelHumpMatcher matcher = new CamelHumpMatcher(prefix); + CompletionSorterImpl sorter = defaultSorter(parameters, matcher); + return new CompletionResultSetImpl(consumer, textBeforePosition, matcher, contributor,parameters, sorter, process, null); + } + + @Override + public CompletionProgressIndicator getCurrentCompletion() { + if (isPhase(CompletionPhase.BgCalculation.class, CompletionPhase.ItemsCalculated.class, CompletionPhase.CommittingDocuments.class, + CompletionPhase.Synchronous.class)) { + return ourPhase.indicator; + } + return null; + } + + private static int getPrefixMatchingDegree(LookupElement item, CompletionLocation location) { + final MinusculeMatcher matcher = getMinusculeMatcher(location.getCompletionParameters().getLookup().itemPattern(item)); + + int max = Integer.MIN_VALUE; + for (String lookupString : item.getAllLookupStrings()) { + max = Math.max(max, matcher.matchingDegree(lookupString)); + } + return max; + } + + private static volatile Pair lastMatcher; + + private static MinusculeMatcher getMinusculeMatcher(String prefix) { + final int setting = ourSettings.COMPLETION_CASE_SENSITIVE; + final NameUtil.MatchingCaseSensitivity sensitivity = + setting == CodeInsightSettings.NONE ? NameUtil.MatchingCaseSensitivity.NONE : + setting == CodeInsightSettings.FIRST_LETTER ? NameUtil.MatchingCaseSensitivity.FIRST_LETTER : NameUtil.MatchingCaseSensitivity.ALL; + + Pair pair = lastMatcher; + if (pair != null && pair.first.equals(prefix)) { + return pair.second; + } + + MinusculeMatcher matcher = new MinusculeMatcher(CamelHumpMatcher.applyMiddleMatching(prefix), sensitivity); + lastMatcher = Pair.create(prefix, matcher); + return matcher; + } + + private static class CompletionResultSetImpl extends CompletionResultSet { + private final String myTextBeforePosition; + private final CompletionParameters myParameters; + private final CompletionSorterImpl mySorter; + private final CompletionProgressIndicator myProcess; + @Nullable private final CompletionResultSetImpl myOriginal; + + public CompletionResultSetImpl(final Consumer consumer, final String textBeforePosition, + final PrefixMatcher prefixMatcher, + CompletionContributor contributor, + CompletionParameters parameters, + @NotNull CompletionSorterImpl sorter, + @NotNull CompletionProgressIndicator process, + @Nullable CompletionResultSetImpl original) { + super(prefixMatcher, consumer, contributor); + myTextBeforePosition = textBeforePosition; + myParameters = parameters; + mySorter = sorter; + myProcess = process; + myOriginal = original; + } + + public void addElement(@NotNull final LookupElement element) { + CompletionResult matched = CompletionResult.wrap(element, getPrefixMatcher(), mySorter); + if (matched != null) { + passResult(matched); + } + } + + @NotNull + public CompletionResultSet withPrefixMatcher(@NotNull final PrefixMatcher matcher) { + if (!myTextBeforePosition.endsWith(matcher.getPrefix())) { + final int len = myTextBeforePosition.length(); + final String fragment = len > 100 ? myTextBeforePosition.substring(len - 100) : myTextBeforePosition; + PsiFile positionFile = myParameters.getPosition().getContainingFile(); + LOG.error("prefix should be some actual file string just before caret: " + matcher.getPrefix() + + "\n text=" + fragment + + "\ninjected=" + (InjectedLanguageUtil.getTopLevelFile(positionFile) != positionFile) + + "\nlang=" + positionFile.getLanguage()); + } + return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, matcher, myContributor, myParameters, mySorter, myProcess, this); + } + + @Override + public void stopHere() { + super.stopHere(); + if (myOriginal != null) { + myOriginal.stopHere(); + } + } + + @NotNull + public CompletionResultSet withPrefixMatcher(@NotNull final String prefix) { + return withPrefixMatcher(new CamelHumpMatcher(prefix)); + } + + @NotNull + @Override + public CompletionResultSet withRelevanceSorter(@NotNull CompletionSorter sorter) { + return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, getPrefixMatcher(), myContributor, myParameters, (CompletionSorterImpl)sorter, myProcess, this); + } + + @NotNull + @Override + public CompletionResultSet caseInsensitive() { + return withPrefixMatcher(new CamelHumpMatcher(getPrefixMatcher().getPrefix(), false)); + } + + @Override + public void restartCompletionOnPrefixChange(ElementPattern prefixCondition) { + final CompletionProgressIndicator indicator = getCompletionService().getCurrentCompletion(); + if (indicator != null) { + indicator.addWatchedPrefix(myTextBeforePosition.length() - getPrefixMatcher().getPrefix().length(), prefixCondition); + } + } + + @Override + public void restartCompletionWhenNothingMatches() { + final CompletionProgressIndicator indicator = getCompletionService().getCurrentCompletion(); + if (indicator != null) { + indicator.getLookup().setStartCompletionWhenNothingMatches(true); + } + } + } + + public static boolean assertPhase(Class... possibilities) { + if (!isPhase(possibilities)) { + LOG.error(ourPhase + "; set at " + ourPhaseTrace); + return false; + } + return true; + } + + public static boolean isPhase(Class... possibilities) { + CompletionPhase phase = getCompletionPhase(); + for (Class possibility : possibilities) { + if (possibility.isInstance(phase)) { + return true; + } + } + return false; + } + + public static void setCompletionPhase(@NotNull CompletionPhase phase) { + ApplicationManager.getApplication().assertIsDispatchThread(); + CompletionPhase oldPhase = getCompletionPhase(); + CompletionProgressIndicator oldIndicator = oldPhase.indicator; + if (oldIndicator != null && !(phase instanceof CompletionPhase.BgCalculation)) { + LOG.assertTrue(!oldIndicator.isRunning() || oldIndicator.isCanceled(), "don't change phase during running completion: oldPhase=" + oldPhase); + } + + Disposer.dispose(oldPhase); + ourPhase = phase; + ourPhaseTrace = DebugUtil.currentStackTrace(); + } + + public static CompletionPhase getCompletionPhase() { +// ApplicationManager.getApplication().assertIsDispatchThread(); + CompletionPhase phase = getPhaseRaw(); + ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); + if (indicator != null) { + indicator.checkCanceled(); + } + return phase; + } + + public static CompletionPhase getPhaseRaw() { + return ourPhase; + } + + public CompletionSorterImpl defaultSorter(CompletionParameters parameters, final PrefixMatcher matcher) { + final CompletionLocation location = new CompletionLocation(parameters); + + CompletionSorterImpl sorter = emptySorter(); + sorter = sorter.withClassifier(new PreferStartMatching(location)); + + for (final Weigher weigher : WeighingService.getWeighers(CompletionService.RELEVANCE_KEY)) { + final String id = weigher.toString(); + if ("prefix".equals(id)) { + sorter = sorter.withClassifier(new PrefixMatchingClassifier(id, location)); + } + else { + sorter = sorter.weigh(new LookupElementWeigher(id, true) { + @Override + public Comparable weigh(@NotNull LookupElement element) { + return weigher.weigh(element, location); + } + }); + } + + } + + if (parameters.getCompletionType() == CompletionType.SMART) { + return sorter; + } + + return sorter.withClassifier("priority", true, new ClassifierFactory("liftShorter") { + @Override + public Classifier createClassifier(final Classifier next) { + return new LiftShorterItemsClassifier(next, new LiftShorterItemsClassifier.LiftingCondition()); + } + }); + } + + public CompletionSorterImpl emptySorter() { + return new CompletionSorterImpl(new ArrayList>()); + } + + private static class PreferStartMatching extends ClassifierFactory { + private final CompletionLocation myLocation; + + public PreferStartMatching(CompletionLocation location) { + super("startMatching"); + myLocation = location; + } + + @Override + public Classifier createClassifier(Classifier next) { + return new ComparingClassifier(next, "startMatching") { + @NotNull + @Override + public Comparable getWeight(LookupElement element) { + PrefixMatcher itemMatcher = myLocation.getCompletionParameters().getLookup().itemMatcher(element); + for (String ls : element.getAllLookupStrings()) { + if (itemMatcher.isStartMatch(ls)) { + return false; + } + } + return true; + } + }; + } + } + + private static class PrefixMatchingClassifier extends ClassifierFactory { + private final String myId; + private final CompletionLocation myLocation; + + public PrefixMatchingClassifier(String id, CompletionLocation location) { + super(id); + myId = id; + myLocation = location; + } + + @Override + public Classifier createClassifier(Classifier next) { + return new ComparingClassifier(next, myId) { + @NotNull + @Override + public Comparable getWeight(LookupElement element) { + return -getPrefixMatchingDegree(element, myLocation); + } + }; + } + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java index 7da9e8db5386..8c74a2250ed9 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java @@ -22,7 +22,6 @@ import com.intellij.util.ProcessingContext; import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; -import gnu.trove.THashMap; import gnu.trove.THashSet; import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.Nullable; @@ -35,8 +34,8 @@ import java.util.*; public class LiftShorterItemsClassifier extends Classifier { private final TreeSet mySortedStrings = new TreeSet(); private final MultiMap myElements = new MultiMap(); - private final Map> myToLiftForSorting = new THashMap>(TObjectHashingStrategy.IDENTITY); - private final Map> myToLiftForPreselection = new THashMap>(TObjectHashingStrategy.IDENTITY); + private final Map> myToLiftForSorting = new IdentityHashMap>(); + private final Map> myToLiftForPreselection = new IdentityHashMap>(); private final MultiMap myPrefixes = new MultiMap(); private final Classifier myNext; private final LiftingCondition myCondition; @@ -122,14 +121,12 @@ public class LiftShorterItemsClassifier extends Classifier { private List liftShorterElements(Iterable source, THashSet lifted, ProcessingContext context) { final Set srcSet = new THashSet(TObjectHashingStrategy.IDENTITY); ContainerUtil.addAll(srcSet, source); - final Set processed = new THashSet(TObjectHashingStrategy.IDENTITY); + final Set processed = new THashSet(srcSet.size(), TObjectHashingStrategy.IDENTITY); boolean forSorting = context.get(CompletionLookupArranger.PURE_RELEVANCE) != Boolean.TRUE; - final List result = new ArrayList(); + final List result = new ArrayList(srcSet.size()); for (LookupElement element : myNext.classify(source, context)) { - assert srcSet.contains(element) : myNext; if (processed.add(element)) { - //System.out.println("element = " + element); List shorter = addShorterElements(srcSet, processed, null, myToLiftForPreselection.get(element)); if (forSorting) { shorter = addShorterElements(srcSet, processed, shorter, myToLiftForSorting.get(element)); @@ -151,7 +148,6 @@ public class LiftShorterItemsClassifier extends Classifier { @Nullable Set from) { if (from != null) { for (LookupElement shorterElement : from) { - //System.out.println("shorterElement = " + shorterElement); if (srcSet.contains(shorterElement) && processed.add(shorterElement)) { if (toLift == null) toLift = new SmartList(); toLift.add(shorterElement); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/AnnotationHolderImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/AnnotationHolderImpl.java index 4931b22a5d75..972109e5907d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/AnnotationHolderImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/AnnotationHolderImpl.java @@ -22,6 +22,7 @@ import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.lang.annotation.AnnotationSession; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; @@ -130,7 +131,7 @@ public class AnnotationHolderImpl extends SmartList implements Annot LOG.assertTrue(containingFile != null, node); VirtualFile containingVFile = containingFile.getVirtualFile(); VirtualFile myVFile = myFile.getVirtualFile(); - if (containingVFile != myVFile) { + if (!Comparing.equal(containingVFile, myVFile)) { LOG.error( "Annotation must be registered for an element inside '" + myFile + "' which is in '" + myVFile + "'.\n" + "Element passed: '" + node + "' is inside the '" + containingFile + "' which is in '" + containingVFile + "'"); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java index 1a8b9ba856d2..6b957ac47126 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java @@ -200,7 +200,7 @@ public class QuickEditHandler extends DocumentAdapter implements Disposable { boolean unsplit = false; if (mySplittedWindow != null && !mySplittedWindow.isDisposed()) { final EditorWithProviderComposite[] editors = mySplittedWindow.getEditors(); - if (editors.length == 1 && editors[0].getFile() == myNewVirtualFile) { + if (editors.length == 1 && Comparing.equal(editors[0].getFile(), myNewVirtualFile)) { unsplit = true; } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/CachingComparingClassifier.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/CachingComparingClassifier.java index e5980778bc7f..683009d5da22 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/CachingComparingClassifier.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/CachingComparingClassifier.java @@ -15,36 +15,31 @@ */ package com.intellij.codeInsight.lookup; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Ref; import com.intellij.psi.ForceableComparable; import com.intellij.util.ProcessingContext; -import gnu.trove.THashMap; -import gnu.trove.TObjectHashingStrategy; -import org.jetbrains.annotations.NotNull; +import java.util.IdentityHashMap; import java.util.Map; /** * @author peter */ public class CachingComparingClassifier extends ComparingClassifier { - private final Map myWeights = new THashMap(TObjectHashingStrategy.IDENTITY); + private final Map myWeights = new IdentityHashMap(); private final LookupElementWeigher myWeigher; - private Comparable myFirstWeight; + private Ref myFirstWeight; private boolean myPrimitive = true; public CachingComparingClassifier(Classifier next, LookupElementWeigher weigher) { - super(next, weigher.toString()); + super(next, weigher.toString(), weigher.isNegated()); myWeigher = weigher; } - @NotNull @Override public final Comparable getWeight(LookupElement t) { - final Comparable weight = myWeights.get(t); - if (weight == null) { - throw new AssertionError(myName + "; " + myWeights.containsKey(t) + "; element=" + t); - } - return weight; + return myWeights.get(t); } @Override @@ -64,8 +59,8 @@ public class CachingComparingClassifier extends ComparingClassifier extends Classifier { protected final Classifier myNext; protected final String myName; + private final boolean myNegated; public ComparingClassifier(Classifier next, String name) { - myNext = next; - myName = name; + this(next, name, false); } - @NotNull + protected ComparingClassifier(Classifier next, String name, boolean negated) { + myNext = next; + myName = name; + myNegated = negated; + } + + @Nullable public abstract Comparable getWeight(T t); public void addElement(T t) { myNext.addElement(t); } - private TreeMap> groupByWeights(Iterable source) { - TreeMap> map = new TreeMap>(); - for (T t : source) { - final Comparable weight = getWeight(t); - List list = map.get(weight); - if (list == null) { - map.put(weight, list = new SmartList()); - } - list.add(t); - } - return map; - } - @Override public Iterable classify(Iterable source, ProcessingContext context) { - List result = new ArrayList(); - for (List list : groupByWeights(source).values()) { - ContainerUtil.addAll(result, myNext.classify(list, context)); + List nulls = null; + TreeMap> map = new TreeMap>(); + int count = 0; + for (T t : myNext.classify(source, context)) { + count++; + final Comparable weight = getWeight(t); + if (weight == null) { + if (nulls == null) nulls = new SmartList(); + nulls.add(t); + } else { + List list = map.get(weight); + if (list == null) { + map.put(weight, list = new SmartList()); + } + list.add(t); + } + } + + ArrayList result = new ArrayList(count); + Collection> values = myNegated ? map.descendingMap().values() : map.values(); + for (List value : values) { + result.addAll(value); + } + if (nulls != null) { + result.addAll(nulls); } return result; } @Override public void describeItems(LinkedHashMap map, ProcessingContext context) { - final Map> treeMap = groupByWeights(new ArrayList(map.keySet())); - if (treeMap.size() > 1 || ApplicationManager.getApplication().isUnitTestMode()) { - for (Map.Entry> entry: treeMap.entrySet()){ - for (T t : entry.getValue()) { - final StringBuilder builder = map.get(t); - if (builder.length() > 0) { - builder.append(", "); - } - - builder.append(myName).append("=").append(entry.getKey()); + Map weights = new IdentityHashMap(); + for (T t : map.keySet()) { + weights.put(t, String.valueOf(getWeight(t))); + } + if (new HashSet(weights.values()).size() > 1 || ApplicationManager.getApplication().isUnitTestMode() || true) { + for (T t : map.keySet()) { + final StringBuilder builder = map.get(t); + if (builder.length() > 0) { + builder.append(", "); } + builder.append(myName).append("=").append(weights.get(t)); } } myNext.describeItems(map, context); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/problems/WolfTheProblemSolverImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/problems/WolfTheProblemSolverImpl.java index d505f8af1210..be1d11f253e5 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/problems/WolfTheProblemSolverImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/problems/WolfTheProblemSolverImpl.java @@ -33,10 +33,7 @@ import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.Condition; -import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.FileStatusListener; import com.intellij.openapi.vcs.FileStatusManager; @@ -333,7 +330,7 @@ public class WolfTheProblemSolverImpl extends WolfTheProblemSolver { Document document = ((TextEditor)editor).getEditor().getDocument(); PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getCachedPsiFile(document); if (psiFile == null) continue; - if (file == psiFile.getVirtualFile()) return true; + if (Comparing.equal(file, psiFile.getVirtualFile())) return true; } return false; } diff --git a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java index e16fa6bfa9ea..5bf76d099df1 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java @@ -51,10 +51,7 @@ import com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl; import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl; import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.Ref; -import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; @@ -583,7 +580,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { myProject.getMessageBus().connect(this).subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new FileEditorManagerAdapter() { @Override public void fileOpened(FileEditorManager source, VirtualFile file) { - if (file != myFile.getVirtualFile()) return; + if (!Comparing.equal(file, myFile.getVirtualFile())) return; if (myConsoleEditor != null) { Editor selectedTextEditor = source.getSelectedTextEditor(); for (FileEditor fileEditor : source.getAllEditors(file)) { @@ -608,7 +605,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { @Override public void fileClosed(FileEditorManager source, VirtualFile file) { - if (file != myFile.getVirtualFile()) return; + if (!Comparing.equal(file, myFile.getVirtualFile())) return; if (myUiUpdateRunnable != null && !Boolean.TRUE.equals(file.getUserData(FileEditorManagerImpl.CLOSING_TO_REOPEN))) { if (myCurrentEditor.isDisposed()) myCurrentEditor = null; ApplicationManager.getApplication().runReadAction(myUiUpdateRunnable); diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java index 9ef7a9e24def..de56727d663e 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java @@ -656,6 +656,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo } if (strings.length > 0) { document.insertString(document.getTextLength(), strings[strings.length - 1]); + myContentSize -= strings.length - 1; } } finally { @@ -1574,8 +1575,8 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo * replace text * * @param s text for replace - * @param start relativly to all document text - * @param end relativly to all document text + * @param start relatively to all document text + * @param end relatively to all document text */ private void replaceUserText(final String s, int start, int end) { if (start == end) { diff --git a/platform/lang-impl/src/com/intellij/execution/rmi/RemoteProcessSupport.java b/platform/lang-impl/src/com/intellij/execution/rmi/RemoteProcessSupport.java index 825fd267402a..2e5306315a6c 100644 --- a/platform/lang-impl/src/com/intellij/execution/rmi/RemoteProcessSupport.java +++ b/platform/lang-impl/src/com/intellij/execution/rmi/RemoteProcessSupport.java @@ -301,7 +301,7 @@ public abstract class RemoteProcessSupport { RemoteDeadHand.TwoMinutesTurkish.startCooking("localhost", result.port); } catch (Exception e) { - LOG.error(e); + LOG.warn("The cook failed to start due to " + ExceptionUtil.getRootCause(e)); } } } diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java index 4b139de03afb..ded203b2c1e8 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java @@ -1,4 +1,3 @@ - /* * Copyright 2000-2012 JetBrains s.r.o. * @@ -414,7 +413,7 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo if(lang == null) return NOT_FOUND_RESULT; CommentsLiteralsSearchData data = model.getUserData(ourCommentsLiteralsSearchDataKey); - if (data == null || data.lastFile != file) { + if (data == null || !Comparing.equal(data.lastFile, file)) { Lexer lexer = getLexer(file, lang); TokenSet tokensOfInterest = TokenSet.EMPTY; diff --git a/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java b/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java index 1154dc8e136f..6e9eb784ada1 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java @@ -13,10 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/** - * @author Alexey - */ package com.intellij.ide.actions; import com.intellij.codeInsight.TargetElementUtilBase; @@ -53,10 +49,69 @@ import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.File; import java.io.IOException; +import java.net.URL; +import java.util.jar.JarFile; +import java.util.zip.ZipEntry; +/** + * @author Alexey + */ public class CopyReferenceAction extends AnAction { - public static final DataFlavor ourFlavor = FileCopyPasteUtil.createJvmDataFlavor(MyTransferable.class); + public static final DataFlavor ourFlavor; + static { + try { + ourFlavor = FileCopyPasteUtil.createJvmDataFlavor(MyTransferable.class); + } + catch (Exception e) { + // todo[r.sh] delete in IDEA 12 + final StringBuilder msg = new StringBuilder(); + final ClassLoader loader = CopyReferenceAction.class.getClassLoader(); + msg.append("loader=").append(loader); + if (loader != null) { + final URL url = loader.getResource("com/intellij/ide/actions/CopyReferenceAction.class"); + msg.append(" url=").append(url); + if (url != null) { + if ("jar".equals(url.getProtocol())) { + String path = url.getFile(); + msg.append(" path=").append(path); + if (path != null && !path.isEmpty()) { + if (path.startsWith("file:") && path.length() > 5) path = path.substring(5); + if (path.startsWith("//") && path.length() > 2) path = path.substring(2); + final String[] parts = path.split("!/"); + if (parts.length == 2) { + try { + final JarFile jar = new JarFile(parts[0]); + try { + msg.append(" jar=").append(jar); + final ZipEntry entry = jar.getEntry(parts[1].replace("CopyReferenceAction.class", "CopyReferenceAction$MyTransferable.class")); + msg.append(" entry=").append(entry); + } + finally { + jar.close(); + } + } + catch (IOException e1) { + msg.append(" io=").append(e1.getMessage()); + throw new RuntimeException(msg.toString(), e); + } + } + } + } + else { + final String path = url.getFile(); + msg.append(" path=").append(path); + if (path != null && !path.isEmpty()) { + final boolean exists = new File(path.replace("CopyReferenceAction.class", "CopyReferenceAction$MyTransferable.class")).exists(); + msg.append(" exists=").append(exists); + } + } + } + } + throw new RuntimeException(msg.toString(), e); + } + } public CopyReferenceAction() { super(); diff --git a/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkManager.java b/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkManager.java index b2b635d7496f..b3264e0daaaa 100644 --- a/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkManager.java +++ b/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkManager.java @@ -28,6 +28,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.DumbAwareRunnable; import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -79,7 +80,7 @@ public class BookmarkManager extends AbstractProjectComponent implements Persist public void run() { if (myProject.isDisposed()) return; for (Bookmark bookmark : myBookmarks) { - if (bookmark.getFile() == file) { + if (Comparing.equal(bookmark.getFile(), file)) { bookmark.createHighlighter((MarkupModelEx)DocumentMarkupModel.forDocument(document, myProject, true)); } } @@ -165,7 +166,7 @@ public class BookmarkManager extends AbstractProjectComponent implements Persist @Nullable public Bookmark findFileBookmark(@NotNull VirtualFile file) { for (Bookmark bookmark : myBookmarks) { - if (bookmark.getFile() == file && bookmark.getLine() == -1) return bookmark; + if (Comparing.equal(bookmark.getFile(), file) && bookmark.getLine() == -1) return bookmark; } return null; diff --git a/platform/lang-impl/src/com/intellij/ide/impl/PatchProjectUtil.java b/platform/lang-impl/src/com/intellij/ide/impl/PatchProjectUtil.java index aa3f1174dca1..9c8ca5ae68e1 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/PatchProjectUtil.java +++ b/platform/lang-impl/src/com/intellij/ide/impl/PatchProjectUtil.java @@ -26,6 +26,7 @@ import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.roots.impl.ModifiableModelCommitter; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.*; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VfsUtil; @@ -104,7 +105,7 @@ public class PatchProjectUtil { if (included.isEmpty()) return; final Set parents = new HashSet(); for (VirtualFile file : included) { - if (file == contentEntry.getFile()) return; + if (Comparing.equal(file, contentEntry.getFile())) return; final VirtualFile parent = file.getParent(); if (parent == null || parents.contains(parent)) continue; parents.add(parent); diff --git a/platform/lang-impl/src/com/intellij/ide/impl/ProjectPaneSelectInTarget.java b/platform/lang-impl/src/com/intellij/ide/impl/ProjectPaneSelectInTarget.java index c7598d63b6d9..72f89bfaa6d0 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/ProjectPaneSelectInTarget.java +++ b/platform/lang-impl/src/com/intellij/ide/impl/ProjectPaneSelectInTarget.java @@ -24,6 +24,7 @@ import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFileSystemItem; @@ -57,7 +58,7 @@ public class ProjectPaneSelectInTarget extends ProjectViewSelectInTarget impleme return true; } - return vFile.getParent() == myProject.getBaseDir(); + return Comparing.equal(vFile.getParent(), myProject.getBaseDir()); } return false; diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootAction.java b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootAction.java index b821f227bbac..4216e5753b28 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootAction.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootAction.java @@ -22,6 +22,7 @@ import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.roots.*; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; @@ -65,7 +66,7 @@ public class MarkRootAction extends AnAction { if (entry != null) { final SourceFolder[] sourceFolders = entry.getSourceFolders(); for (SourceFolder sourceFolder : sourceFolders) { - if (sourceFolder.getFile() == vFile) { + if (Comparing.equal(sourceFolder.getFile(), vFile)) { entry.removeSourceFolder(sourceFolder); break; } @@ -126,7 +127,7 @@ public class MarkRootAction extends AnAction { if (!fileIndex.isInContent(vFile)) { return false; } - if (fileIndex.getSourceRootForFile(vFile) == vFile) { + if (Comparing.equal(fileIndex.getSourceRootForFile(vFile), vFile)) { boolean isTestSourceRoot = fileIndex.isInTestSourceContent(vFile); if (acceptSourceRoot && !isTestSourceRoot) { if (rootType != null) rootType.set(true); diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectRootsUtil.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectRootsUtil.java index 84109a989960..42dc2bd3954e 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectRootsUtil.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectRootsUtil.java @@ -18,6 +18,7 @@ package com.intellij.ide.projectView.impl; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.*; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDirectory; @@ -63,7 +64,7 @@ public class ProjectRootsUtil { for (ContentEntry contentEntry : contentEntries) { final SourceFolder[] sourceFolders = contentEntry.getSourceFolders(); for (SourceFolder sourceFolder : sourceFolders) { - if (virtualFile == sourceFolder.getFile()) return true; + if (Comparing.equal(virtualFile, sourceFolder.getFile())) return true; } } return false; diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java index e621f8dac500..c897b0d765fd 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java @@ -113,7 +113,7 @@ public class ProjectViewDirectoryHelper { public boolean canRepresent(Object element, PsiDirectory directory) { if (element instanceof VirtualFile) { VirtualFile vFile = (VirtualFile) element; - return directory.getVirtualFile() == vFile; + return Comparing.equal(directory.getVirtualFile(), vFile); } return false; } @@ -180,7 +180,7 @@ public class ProjectViewDirectoryHelper { while (current != null) { VirtualFile parent = current.getParent(); - if (parent == dir) { + if (Comparing.equal(parent, dir)) { final PsiDirectory psi = manager.findDirectory(current); if (psi != null) { directoriesOnTheWayToContentRoots.add(psi); diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java index 79c443dd51aa..9a35f9b89676 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java @@ -298,7 +298,7 @@ public class PsiDirectoryNode extends BasePsiNode implements Navig if (ProjectAttachProcessor.canAttachToProject()) { // primary module is always on top; attached modules are sorted alphabetically final VirtualFile file = getVirtualFile(); - if (file == myProject.getBaseDir()) { + if (Comparing.equal(file, myProject.getBaseDir())) { return ""; // sorts before any other name } return getTitle(); diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiFileNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiFileNode.java index b53889ffb4d1..d7258fcd05a4 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiFileNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiFileNode.java @@ -26,6 +26,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.roots.libraries.LibraryUtil; import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Iconable; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.JarFileSystem; @@ -175,6 +176,6 @@ public class PsiFileNode extends BasePsiNode implements NavigatableWith @Override public boolean contains(@NotNull VirtualFile file) { - return super.contains(file) || isArchive() && PathUtil.getLocalFile(file) == getVirtualFile(); + return super.contains(file) || isArchive() && Comparing.equal(PathUtil.getLocalFile(file), getVirtualFile()); } } diff --git a/platform/lang-impl/src/com/intellij/lang/LanguagePerFileMappings.java b/platform/lang-impl/src/com/intellij/lang/LanguagePerFileMappings.java index d5a4fa9703f8..a5aa44f17a8a 100644 --- a/platform/lang-impl/src/com/intellij/lang/LanguagePerFileMappings.java +++ b/platform/lang-impl/src/com/intellij/lang/LanguagePerFileMappings.java @@ -21,6 +21,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.impl.FilePropertyPusher; import com.intellij.openapi.roots.impl.PushedFilePropertiesUpdater; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.testFramework.LightVirtualFile; @@ -76,7 +77,7 @@ public abstract class LanguagePerFileMappings implements PersistentStateCompo file = window.getDelegate(); } VirtualFile originalFile = file instanceof LightVirtualFile ? ((LightVirtualFile)file).getOriginalFile() : null; - if (originalFile == file) originalFile = null; + if (Comparing.equal(originalFile, file)) originalFile = null; if (file != null) { final FilePropertyPusher pusher = getFilePropertyPusher(); diff --git a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/PsiAwareFileEditorManagerImpl.java b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/PsiAwareFileEditorManagerImpl.java index 5118581eb4ef..bd6b2dece58e 100644 --- a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/PsiAwareFileEditorManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/PsiAwareFileEditorManagerImpl.java @@ -1,168 +1,170 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.intellij.openapi.fileEditor.impl; - -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.fileEditor.impl.text.TextEditorPsiDataProvider; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleUtil; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.problems.WolfTheProblemSolver; -import com.intellij.psi.*; -import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; -import com.intellij.ui.ColorUtil; -import com.intellij.ui.docking.DockManager; -import org.jetbrains.annotations.NotNull; - -import java.awt.*; - -/** - * @author yole - */ -public class PsiAwareFileEditorManagerImpl extends FileEditorManagerImpl { - private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.text.PsiAwareFileEditorManagerImpl"); - - private final PsiManager myPsiManager; - private final WolfTheProblemSolver myProblemSolver; - - /** - * Updates icons for open files when project roots change - */ - private final MyPsiTreeChangeListener myPsiTreeChangeListener; - private final WolfTheProblemSolver.ProblemListener myProblemListener; - - public PsiAwareFileEditorManagerImpl(final Project project, final PsiManager psiManager, final WolfTheProblemSolver problemSolver, DockManager dockManager) { - super(project, dockManager); - myPsiManager = psiManager; - myProblemSolver = problemSolver; - myPsiTreeChangeListener = new MyPsiTreeChangeListener(); - myProblemListener = new MyProblemListener(); - registerExtraEditorDataProvider(new TextEditorPsiDataProvider(), null); - } - - @Override - public void projectOpened() { - super.projectOpened(); //To change body of overridden methods use File | Settings | File Templates. - myPsiManager.addPsiTreeChangeListener(myPsiTreeChangeListener); - myProblemSolver.addProblemListener(myProblemListener); - } - - @Override - public Color getFileColor(@NotNull final VirtualFile file) { - Color color = super.getFileColor(file); - if (myProblemSolver.isProblemFile(file)) { - return ColorUtil.toAlpha(color, WaverGraphicsDecorator.WAVE_ALPHA_KEY); - } - return color; - } - - public boolean isProblem(@NotNull final VirtualFile file) { - return myProblemSolver.isProblemFile(file); - } - - public String getFileTooltipText(final VirtualFile file) { - final StringBuilder tooltipText = new StringBuilder(); - final Module module = ModuleUtil.findModuleForFile(file, getProject()); - if (module != null) { - tooltipText.append("["); - tooltipText.append(module.getName()); - tooltipText.append("] "); - } - tooltipText.append(FileUtil.getLocationRelativeToUserHome(file.getPresentableUrl())); - return tooltipText.toString(); - } - - @Override - protected Editor getOpenedEditor(final Editor editor, final boolean focusEditor) { - PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getProject()); - Document document = editor.getDocument(); - PsiFile psiFile = documentManager.getPsiFile(document); - if (!focusEditor || documentManager.isUncommited(document)) { - return editor; - } - - return InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(editor, psiFile); - } - - /** - * Updates attribute of open files when roots change - */ - private final class MyPsiTreeChangeListener extends PsiTreeChangeAdapter { - public void propertyChanged(@NotNull final PsiTreeChangeEvent e) { - if (PsiTreeChangeEvent.PROP_ROOTS.equals(e.getPropertyName())) { - ApplicationManager.getApplication().assertIsDispatchThread(); - final VirtualFile[] openFiles = getOpenFiles(); - for (int i = openFiles.length - 1; i >= 0; i--) { - final VirtualFile file = openFiles[i]; - LOG.assertTrue(file != null); - updateFileIcon(file); - } - } - } - - public void childAdded(@NotNull PsiTreeChangeEvent event) { - doChange(event); - } - - public void childRemoved(@NotNull PsiTreeChangeEvent event) { - doChange(event); - } - - public void childReplaced(@NotNull PsiTreeChangeEvent event) { - doChange(event); - } - - public void childMoved(@NotNull PsiTreeChangeEvent event) { - doChange(event); - } - - public void childrenChanged(@NotNull PsiTreeChangeEvent event) { - doChange(event); - } - - private void doChange(final PsiTreeChangeEvent event) { - final PsiFile psiFile = event.getFile(); - final VirtualFile currentFile = getCurrentFile(); - if (currentFile != null && psiFile != null && psiFile.getVirtualFile() == currentFile) { - updateFileIcon(currentFile); - } - } - } - - private class MyProblemListener extends WolfTheProblemSolver.ProblemListener { - public void problemsAppeared(final VirtualFile file) { - updateFile(file); - } - - public void problemsDisappeared(VirtualFile file) { - updateFile(file); - } - - public void problemsChanged(VirtualFile file) { - updateFile(file); - } - - private void updateFile(final VirtualFile file) { - queueUpdateFile(file); - } - } -} +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intellij.openapi.fileEditor.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.impl.text.TextEditorPsiDataProvider; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.io.FileUtil; + +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.problems.WolfTheProblemSolver; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; +import com.intellij.ui.ColorUtil; +import com.intellij.ui.docking.DockManager; +import org.jetbrains.annotations.NotNull; + +import java.awt.*; + +/** + * @author yole + */ +public class PsiAwareFileEditorManagerImpl extends FileEditorManagerImpl { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.text.PsiAwareFileEditorManagerImpl"); + + private final PsiManager myPsiManager; + private final WolfTheProblemSolver myProblemSolver; + + /** + * Updates icons for open files when project roots change + */ + private final MyPsiTreeChangeListener myPsiTreeChangeListener; + private final WolfTheProblemSolver.ProblemListener myProblemListener; + + public PsiAwareFileEditorManagerImpl(final Project project, final PsiManager psiManager, final WolfTheProblemSolver problemSolver, DockManager dockManager) { + super(project, dockManager); + myPsiManager = psiManager; + myProblemSolver = problemSolver; + myPsiTreeChangeListener = new MyPsiTreeChangeListener(); + myProblemListener = new MyProblemListener(); + registerExtraEditorDataProvider(new TextEditorPsiDataProvider(), null); + } + + @Override + public void projectOpened() { + super.projectOpened(); //To change body of overridden methods use File | Settings | File Templates. + myPsiManager.addPsiTreeChangeListener(myPsiTreeChangeListener); + myProblemSolver.addProblemListener(myProblemListener); + } + + @Override + public Color getFileColor(@NotNull final VirtualFile file) { + Color color = super.getFileColor(file); + if (myProblemSolver.isProblemFile(file)) { + return ColorUtil.toAlpha(color, WaverGraphicsDecorator.WAVE_ALPHA_KEY); + } + return color; + } + + public boolean isProblem(@NotNull final VirtualFile file) { + return myProblemSolver.isProblemFile(file); + } + + public String getFileTooltipText(final VirtualFile file) { + final StringBuilder tooltipText = new StringBuilder(); + final Module module = ModuleUtil.findModuleForFile(file, getProject()); + if (module != null) { + tooltipText.append("["); + tooltipText.append(module.getName()); + tooltipText.append("] "); + } + tooltipText.append(FileUtil.getLocationRelativeToUserHome(file.getPresentableUrl())); + return tooltipText.toString(); + } + + @Override + protected Editor getOpenedEditor(final Editor editor, final boolean focusEditor) { + PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getProject()); + Document document = editor.getDocument(); + PsiFile psiFile = documentManager.getPsiFile(document); + if (!focusEditor || documentManager.isUncommited(document)) { + return editor; + } + + return InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(editor, psiFile); + } + + /** + * Updates attribute of open files when roots change + */ + private final class MyPsiTreeChangeListener extends PsiTreeChangeAdapter { + public void propertyChanged(@NotNull final PsiTreeChangeEvent e) { + if (PsiTreeChangeEvent.PROP_ROOTS.equals(e.getPropertyName())) { + ApplicationManager.getApplication().assertIsDispatchThread(); + final VirtualFile[] openFiles = getOpenFiles(); + for (int i = openFiles.length - 1; i >= 0; i--) { + final VirtualFile file = openFiles[i]; + LOG.assertTrue(file != null); + updateFileIcon(file); + } + } + } + + public void childAdded(@NotNull PsiTreeChangeEvent event) { + doChange(event); + } + + public void childRemoved(@NotNull PsiTreeChangeEvent event) { + doChange(event); + } + + public void childReplaced(@NotNull PsiTreeChangeEvent event) { + doChange(event); + } + + public void childMoved(@NotNull PsiTreeChangeEvent event) { + doChange(event); + } + + public void childrenChanged(@NotNull PsiTreeChangeEvent event) { + doChange(event); + } + + private void doChange(final PsiTreeChangeEvent event) { + final PsiFile psiFile = event.getFile(); + final VirtualFile currentFile = getCurrentFile(); + if (currentFile != null && psiFile != null && Comparing.equal(psiFile.getVirtualFile(), currentFile)) { + updateFileIcon(currentFile); + } + } + } + + private class MyProblemListener extends WolfTheProblemSolver.ProblemListener { + public void problemsAppeared(final VirtualFile file) { + updateFile(file); + } + + public void problemsDisappeared(VirtualFile file) { + updateFile(file); + } + + public void problemsChanged(VirtualFile file) { + updateFile(file); + } + + private void updateFile(final VirtualFile file) { + queueUpdateFile(file); + } + } +} diff --git a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/TestEditorManagerImpl.java b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/TestEditorManagerImpl.java index 26ac8a341b86..44b42d3dfcc8 100644 --- a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/TestEditorManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/TestEditorManagerImpl.java @@ -33,6 +33,7 @@ import com.intellij.openapi.fileEditor.impl.text.TextEditorPsiDataProvider; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.AsyncResult; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -331,7 +332,7 @@ import java.util.Map; if (editor != null){ EditorFactory.getInstance().releaseEditor(editor); } - if (file == myActiveFile) myActiveFile = null; + if (Comparing.equal(file, myActiveFile)) myActiveFile = null; } @Override diff --git a/platform/lang-impl/src/com/intellij/openapi/vcs/changes/patch/PsiPatchBaseDirectoryDetector.java b/platform/lang-impl/src/com/intellij/openapi/vcs/changes/patch/PsiPatchBaseDirectoryDetector.java index 5910887431b7..99520def4ac9 100644 --- a/platform/lang-impl/src/com/intellij/openapi/vcs/changes/patch/PsiPatchBaseDirectoryDetector.java +++ b/platform/lang-impl/src/com/intellij/openapi/vcs/changes/patch/PsiPatchBaseDirectoryDetector.java @@ -17,6 +17,7 @@ package com.intellij.openapi.vcs.changes.patch; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiFile; @@ -47,7 +48,7 @@ public class PsiPatchBaseDirectoryDetector extends PatchBaseDirectoryDetector { if (psiFiles.length == 1) { PsiDirectory parent = psiFiles [0].getContainingDirectory(); for(int i=nameComponents.length-2; i >= 0; i--) { - if (!parent.getName().equals(nameComponents [i]) || parent.getVirtualFile() == myProject.getBaseDir()) { + if (!parent.getName().equals(nameComponents[i]) || Comparing.equal(parent.getVirtualFile(), myProject.getBaseDir())) { return new Result(parent.getVirtualFile().getPresentableUrl(), i+1); } parent = parent.getParentDirectory(); diff --git a/platform/lang-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesModuleGroupingPolicy.java b/platform/lang-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesModuleGroupingPolicy.java index c44bf20793d9..2bde879b0205 100644 --- a/platform/lang-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesModuleGroupingPolicy.java +++ b/platform/lang-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesModuleGroupingPolicy.java @@ -20,6 +20,7 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.Nullable; @@ -48,7 +49,7 @@ public class ChangesModuleGroupingPolicy implements ChangesGroupingPolicy { ProjectFileIndex index = ProjectRootManager.getInstance(myProject).getFileIndex(); VirtualFile vFile = node.getVf(); - if (vFile != null && vFile == index.getContentRootForFile(vFile)) { + if (vFile != null && Comparing.equal(vFile, index.getContentRootForFile(vFile))) { Module module = index.getModuleForFile(vFile); return getNodeForModule(module, rootNode); } diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/ui/DirectoryNode.java b/platform/lang-impl/src/com/intellij/packageDependencies/ui/DirectoryNode.java index ff4f11f5e5e0..21ec2f02fcf1 100644 --- a/platform/lang-impl/src/com/intellij/packageDependencies/ui/DirectoryNode.java +++ b/platform/lang-impl/src/com/intellij/packageDependencies/ui/DirectoryNode.java @@ -21,6 +21,7 @@ import com.intellij.ide.projectView.impl.nodes.ProjectViewDirectoryHelper; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; @@ -61,12 +62,12 @@ public class DirectoryNode extends PackageDependenciesNode { if (showFQName) { final VirtualFile contentRoot = index.getContentRootForFile(myVDirectory); if (contentRoot != null) { - if (myVDirectory == contentRoot) { + if (Comparing.equal(myVDirectory, contentRoot)) { myFQName = dirName; } else { final VirtualFile sourceRoot = index.getSourceRootForFile(myVDirectory); - if (myVDirectory == sourceRoot) { + if (Comparing.equal(myVDirectory, sourceRoot)) { myFQName = VfsUtilCore.getRelativePath(myVDirectory, contentRoot, '/'); } else if (sourceRoot != null) { @@ -96,10 +97,11 @@ public class DirectoryNode extends PackageDependenciesNode { private String getContentRootName(final VirtualFile baseDir, final String dirName) { if (baseDir != null) { - if (myVDirectory != baseDir) { + if (!Comparing.equal(myVDirectory, baseDir)) { if (VfsUtil.isAncestor(baseDir, myVDirectory, false)) { return VfsUtilCore.getRelativePath(myVDirectory, baseDir, '/'); - } else { + } + else { return myVDirectory.getPresentableUrl(); } } @@ -140,7 +142,7 @@ public class DirectoryNode extends PackageDependenciesNode { final ProjectFileIndex index = ProjectRootManager.getInstance(myProject).getFileIndex(); VirtualFile directory = myVDirectory; VirtualFile contentRoot = index.getContentRootForFile(directory); - if (directory == contentRoot) { + if (Comparing.equal(directory, contentRoot)) { return ""; } if (contentRoot == null) { diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/ui/FileTreeModelBuilder.java b/platform/lang-impl/src/com/intellij/packageDependencies/ui/FileTreeModelBuilder.java index 2d5ad682d109..ce552ade2d90 100644 --- a/platform/lang-impl/src/com/intellij/packageDependencies/ui/FileTreeModelBuilder.java +++ b/platform/lang-impl/src/com/intellij/packageDependencies/ui/FileTreeModelBuilder.java @@ -30,6 +30,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ContentIterator; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VfsUtil; @@ -431,7 +432,7 @@ public class FileTreeModelBuilder { else if (node instanceof FileNode) { //non java files psiFile = ((PsiFile)node.getPsiElement()); } - if (psiFile != null && psiFile.getVirtualFile() == ((PsiFile)element).getVirtualFile()) { + if (psiFile != null && Comparing.equal(psiFile.getVirtualFile(), ((PsiFile)element).getVirtualFile())) { result.add(node); } } @@ -497,7 +498,7 @@ public class FileTreeModelBuilder { final VirtualFile directory = virtualFile.getParent(); if (!myFlattenPackages && directory != null) { - if (myCompactEmptyMiddlePackages && sourceRoot != virtualFile && contentRoot != virtualFile) {//compact + if (myCompactEmptyMiddlePackages && !Comparing.equal(sourceRoot, virtualFile) && !Comparing.equal(contentRoot, virtualFile)) {//compact ((DirectoryNode)directoryNode).setCompactedDirNode(childNode); } if (fileIndex.getModuleForFile(directory) == module) { @@ -505,7 +506,7 @@ public class FileTreeModelBuilder { if (parentDirectoryNode != null || !myCompactEmptyMiddlePackages || (sourceRoot != null && VfsUtil.isAncestor(directory, sourceRoot, false) && fileIndex.getSourceRootForFile(directory) != null) - || directory == contentRoot) { + || Comparing.equal(directory, contentRoot)) { getModuleDirNode(directory, module, (DirectoryNode)directoryNode).add(directoryNode); } else { @@ -517,15 +518,18 @@ public class FileTreeModelBuilder { } } else { - if (contentRoot == virtualFile) { + if (Comparing.equal(contentRoot, virtualFile)) { getModuleNode(module).add(directoryNode); - } else { + } + else { final VirtualFile root; - if (sourceRoot != virtualFile && sourceRoot != null) { + if (!Comparing.equal(sourceRoot, virtualFile) && sourceRoot != null) { root = sourceRoot; - } else if (contentRoot != null) { + } + else if (contentRoot != null) { root = contentRoot; - } else { + } + else { root = null; } if (root != null) { @@ -586,7 +590,7 @@ public class FileTreeModelBuilder { public boolean processFile(VirtualFile fileOrDir) { if (!fileOrDir.isDirectory()) { - if (lastParent != null && dir != fileOrDir.getParent()) { + if (lastParent != null && !Comparing.equal(dir, fileOrDir.getParent())) { lastParent = null; } lastParent = buildFileNode(fileOrDir, lastParent); diff --git a/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.java b/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.java index 188c848c7d8e..94da68fb6c47 100644 --- a/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.java +++ b/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.java @@ -29,6 +29,7 @@ import com.intellij.openapi.project.ex.ProjectManagerEx; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vcs.AbstractVcs; @@ -160,7 +161,7 @@ public class ModuleAttachProcessor extends ProjectAttachProcessor { for (Module module : ModuleManager.getInstance(project).getModules()) { final VirtualFile[] roots = ModuleRootManager.getInstance(module).getContentRoots(); for (VirtualFile root : roots) { - if (root == project.getBaseDir()) { + if (Comparing.equal(root, project.getBaseDir())) { return module; } } diff --git a/platform/lang-impl/src/com/intellij/platform/PlatformProjectViewStructureProvider.java b/platform/lang-impl/src/com/intellij/platform/PlatformProjectViewStructureProvider.java index bd2681310c9a..f277acd8c552 100644 --- a/platform/lang-impl/src/com/intellij/platform/PlatformProjectViewStructureProvider.java +++ b/platform/lang-impl/src/com/intellij/platform/PlatformProjectViewStructureProvider.java @@ -23,6 +23,7 @@ import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDirectory; @@ -43,7 +44,7 @@ public class PlatformProjectViewStructureProvider implements TreeStructureProvid public Collection modify(final AbstractTreeNode parent, final Collection children, final ViewSettings settings) { if (parent instanceof PsiDirectoryNode) { final VirtualFile vFile = ((PsiDirectoryNode)parent).getVirtualFile(); - if (vFile != null && ProjectFileIndex.SERVICE.getInstance(myProject).getContentRootForFile(vFile) == vFile) { + if (vFile != null && Comparing.equal(ProjectFileIndex.SERVICE.getInstance(myProject).getContentRootForFile(vFile), vFile)) { final Collection moduleChildren = ((PsiDirectoryNode) parent).getChildren(); Collection result = new ArrayList(); for (AbstractTreeNode moduleChild : moduleChildren) { diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/FileElementInfo.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/FileElementInfo.java index 8fd306cb49b1..628dd65c6005 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/FileElementInfo.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/FileElementInfo.java @@ -71,7 +71,7 @@ class FileElementInfo implements SmartPointerElementInfo { @Override public boolean pointsToTheSameElementAs(@NotNull SmartPointerElementInfo other) { if (other instanceof FileElementInfo) { - return myVirtualFile == ((FileElementInfo)other).myVirtualFile; + return Comparing.equal(myVirtualFile, ((FileElementInfo)other).myVirtualFile); } return Comparing.equal(restoreElement(), other.restoreElement()); } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java index c8d1b63fb577..423d187dff4f 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java @@ -286,12 +286,12 @@ public class SelfElementInfo implements SmartPointerElementInfo { public boolean pointsToTheSameElementAs(@NotNull SmartPointerElementInfo other) { if (other instanceof SelfElementInfo) { SelfElementInfo otherInfo = (SelfElementInfo)other; - return myVirtualFile == otherInfo.myVirtualFile - && myType == otherInfo.myType - && mySyncMarkerIsValid - && otherInfo.mySyncMarkerIsValid - && mySyncStartOffset == otherInfo.mySyncStartOffset - && mySyncEndOffset == otherInfo.mySyncEndOffset + return Comparing.equal(myVirtualFile, otherInfo.myVirtualFile) + && myType == otherInfo.myType + && mySyncMarkerIsValid + && otherInfo.mySyncMarkerIsValid + && mySyncStartOffset == otherInfo.mySyncStartOffset + && mySyncEndOffset == otherInfo.mySyncEndOffset ; } return Comparing.equal(restoreElement(), other.restoreElement()); diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PsiFileReferenceHelper.java b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PsiFileReferenceHelper.java index fb8b400ebbcf..70430ac59874 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PsiFileReferenceHelper.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PsiFileReferenceHelper.java @@ -23,6 +23,7 @@ import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.impl.DirectoryIndex; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; @@ -84,7 +85,7 @@ public class PsiFileReferenceHelper extends FileReferenceHelper { if (orderEntry instanceof ModuleSourceOrderEntry) { for(ContentEntry e: ((ModuleSourceOrderEntry)orderEntry).getRootModel().getContentEntries()) { for(SourceFolder sf:e.getSourceFolders()) { - if (sf.getFile() == root) { + if (Comparing.equal(sf.getFile(), root)) { String s = sf.getPackagePrefix(); if (s.length() > 0) { path = s + "." + path; diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java index d1ee84f27989..615c58974177 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java @@ -345,7 +345,10 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar, ModificationT assert documentWindow.getText().equals(psiFile.getText()) : "Document window text mismatch"; assert injectedFileViewProvider.getDocument() == documentWindow : "Provider document mismatch"; assert documentManager.getCachedDocument(psiFile) == documentWindow : "Cached document mismatch"; - assert psiFile.getVirtualFile() == injectedFileViewProvider.getVirtualFile() : "Virtual file mismatch: "+psiFile.getVirtualFile()+"; "+injectedFileViewProvider.getVirtualFile(); + assert Comparing.equal(psiFile.getVirtualFile(), injectedFileViewProvider.getVirtualFile()) : "Virtual file mismatch: " + + psiFile.getVirtualFile() + + "; " + + injectedFileViewProvider.getVirtualFile(); PsiDocumentManagerImpl.checkConsistency(psiFile, documentWindow); } diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandlerBase.java b/platform/lang-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandlerBase.java index 5e1d334817f7..d826950a525b 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandlerBase.java @@ -29,6 +29,7 @@ import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDirectory; @@ -67,7 +68,7 @@ public abstract class DirectoryAsPackageRenameHandlerBase> myIndexStamps; - private boolean myIsDirty = false; - - private Timestamps(@Nullable DataInputStream stream) throws IOException { - if (stream != null) { - try { - if (stream.available() > 0) { - long dominatingIndexStamp = DataInputOutputUtil.readTIME(stream); - while(stream.available() > 0) { - ID id = ID.findById(DataInputOutputUtil.readINT(stream)); - if (id != null) { - long stamp = IndexInfrastructure.getIndexCreationStamp(id); - if (myIndexStamps == null) myIndexStamps = new TObjectLongHashMap>(5, 0.98f); - if (stamp <= dominatingIndexStamp) myIndexStamps.put(id, stamp); - } - } - } - } - finally { - stream.close(); - } - } - } - - private void writeToStream(final DataOutputStream stream) throws IOException { - if (myIndexStamps != null) { - final long[] dominatingIndexStamp = new long[1]; - myIndexStamps.forEachEntry( - new TObjectLongProcedure>() { - @Override - public boolean execute(ID a, long b) { - dominatingIndexStamp[0] = Math.max(dominatingIndexStamp[0], b); - return true; - } - } - ); - DataInputOutputUtil.writeTIME(stream, dominatingIndexStamp[0]); - myIndexStamps.forEachEntry(new TObjectLongProcedure>() { - @Override - public boolean execute(final ID id, final long timestamp) { - try { - DataInputOutputUtil.writeINT(stream, id.getUniqueId()); - return true; - } - catch (IOException e) { - throw new RuntimeException(e); - } - } - }); - } - } - - public long get(ID id) { - return myIndexStamps != null? myIndexStamps.get(id) : 0L; - } - - public void set(ID id, long tmst) { - try { - if (tmst < 0) { - if (myIndexStamps == null) return; - myIndexStamps.remove(id); - return; - } - if (myIndexStamps == null) myIndexStamps = new TObjectLongHashMap>(5, 0.98f); - - myIndexStamps.put(id, tmst); - } - finally { - myIsDirty = true; - } - } - - public boolean isDirty() { - return myIsDirty; - } - } - - private static final ConcurrentHashMap myTimestampsCache = new ConcurrentHashMap(); - private static final int CAPACITY = 100; - private static final ArrayBlockingQueue myFinishedFiles = new ArrayBlockingQueue(CAPACITY); - - public static boolean isFileIndexed(VirtualFile file, ID indexName, final long indexCreationStamp) { - try { - return getIndexStamp(file, indexName) == indexCreationStamp; - } - catch (RuntimeException e) { - final Throwable cause = e.getCause(); - if (!(cause instanceof IOException)) { - throw e; // in case of IO exceptions consider file unindexed - } - } - - return false; - } - - public static long getIndexStamp(VirtualFile file, ID indexName) { - synchronized (file) { - Timestamps stamp = createOrGetTimeStamp(file); - if (stamp != null) return stamp.get(indexName); - return 0; - } - } - - private static Timestamps createOrGetTimeStamp(VirtualFile file) { - if (file instanceof NewVirtualFile && file.isValid()) { - Timestamps timestamps = myTimestampsCache.get(file); - if (timestamps == null) { - synchronized (myTimestampsCache) { // avoid synchroneous reads TODO: - timestamps = myTimestampsCache.get(file); - if (timestamps == null) { - final DataInputStream stream = Timestamps.PERSISTENCE.readAttribute(file); - try { - timestamps = new Timestamps(stream); - } - catch (IOException e) { - throw new RuntimeException(e); - } - myTimestampsCache.put(file, timestamps); - } - } - } - return timestamps; - } - return null; - } - - public static void update(final VirtualFile file, final ID indexName, final long indexCreationStamp) { - synchronized (file) { - try { - Timestamps stamp = createOrGetTimeStamp(file); - if (stamp != null) stamp.set(indexName, indexCreationStamp); - } - catch (InvalidVirtualFileAccessException ignored /*ok to ignore it here*/) { - } - } - } - - public static void flushCache(@Nullable VirtualFile finishedFile) { - if (finishedFile == null || !myFinishedFiles.offer(finishedFile)) { - VirtualFile[] files = null; - synchronized (myFinishedFiles) { - int size = myFinishedFiles.size(); - if ((finishedFile == null && size > 0) || size == CAPACITY) { - files = myFinishedFiles.toArray(new VirtualFile[size]); - myFinishedFiles.clear(); - } - } - - if (files != null) { - for(VirtualFile file:files) { - synchronized (file) { - Timestamps timestamp = myTimestampsCache.remove(file); - if (timestamp == null) continue; - synchronized (myTimestampsCache) { - try { - if (timestamp.isDirty() && file.isValid()) { - final DataOutputStream sink = Timestamps.PERSISTENCE.writeAttribute(file); - timestamp.writeToStream(sink); - sink.close(); - } - } - catch (IOException e) { - throw new RuntimeException(e); - } - } - } - } - } - if (finishedFile != null) myFinishedFiles.offer(finishedFile); - } - } -} +/* + * Copyright 2000-2009 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.openapi.vfs.InvalidVirtualFileAccessException; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.newvfs.FileAttribute; +import com.intellij.openapi.vfs.newvfs.NewVirtualFile; +import com.intellij.util.containers.ConcurrentHashMap; +import com.intellij.util.io.DataInputOutputUtil; +import gnu.trove.TObjectLongHashMap; +import gnu.trove.TObjectLongProcedure; +import org.jetbrains.annotations.Nullable; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.concurrent.ArrayBlockingQueue; + +/** + * @author Eugene Zhuravlev + * Date: Dec 25, 2007 + */ +public class IndexingStamp { + private IndexingStamp() { + } + + /** + * The class is meant to be accessed from synchronized block only + */ + private static class Timestamps { + private static final FileAttribute PERSISTENCE = new FileAttribute("__index_stamps__", 1, false); + private TObjectLongHashMap> myIndexStamps; + private boolean myIsDirty = false; + + private Timestamps(@Nullable DataInputStream stream) throws IOException { + if (stream != null) { + try { + + long dominatingIndexStamp = DataInputOutputUtil.readTIME(stream); + while(stream.available() > 0) { + ID id = ID.findById(DataInputOutputUtil.readINT(stream)); + if (id != null) { + long stamp = IndexInfrastructure.getIndexCreationStamp(id); + if (myIndexStamps == null) myIndexStamps = new TObjectLongHashMap>(5, 0.98f); + if (stamp <= dominatingIndexStamp) myIndexStamps.put(id, stamp); + } + } + } + finally { + stream.close(); + } + } + } + + private void writeToStream(final DataOutputStream stream) throws IOException { + if (myIndexStamps != null && !myIndexStamps.isEmpty()) { + final long[] dominatingIndexStamp = new long[1]; + myIndexStamps.forEachEntry( + new TObjectLongProcedure>() { + @Override + public boolean execute(ID a, long b) { + dominatingIndexStamp[0] = Math.max(dominatingIndexStamp[0], b); + return true; + } + } + ); + DataInputOutputUtil.writeTIME(stream, dominatingIndexStamp[0]); + myIndexStamps.forEachEntry(new TObjectLongProcedure>() { + @Override + public boolean execute(final ID id, final long timestamp) { + try { + DataInputOutputUtil.writeINT(stream, id.getUniqueId()); + return true; + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + }); + } else { + DataInputOutputUtil.writeTIME(stream, DataInputOutputUtil.timeBase); + } + } + + public long get(ID id) { + return myIndexStamps != null? myIndexStamps.get(id) : 0L; + } + + public void set(ID id, long tmst) { + try { + if (tmst < 0) { + if (myIndexStamps == null) return; + myIndexStamps.remove(id); + return; + } + if (myIndexStamps == null) myIndexStamps = new TObjectLongHashMap>(5, 0.98f); + + myIndexStamps.put(id, tmst); + } + finally { + myIsDirty = true; + } + } + + public boolean isDirty() { + return myIsDirty; + } + } + + private static final ConcurrentHashMap myTimestampsCache = new ConcurrentHashMap(); + private static final int CAPACITY = 100; + private static final ArrayBlockingQueue myFinishedFiles = new ArrayBlockingQueue(CAPACITY); + + public static boolean isFileIndexed(VirtualFile file, ID indexName, final long indexCreationStamp) { + try { + return getIndexStamp(file, indexName) == indexCreationStamp; + } + catch (RuntimeException e) { + final Throwable cause = e.getCause(); + if (!(cause instanceof IOException)) { + throw e; // in case of IO exceptions consider file unindexed + } + } + + return false; + } + + public static long getIndexStamp(VirtualFile file, ID indexName) { + synchronized (file) { + Timestamps stamp = createOrGetTimeStamp(file); + if (stamp != null) return stamp.get(indexName); + return 0; + } + } + + private static Timestamps createOrGetTimeStamp(VirtualFile file) { + if (file instanceof NewVirtualFile && file.isValid()) { + Timestamps timestamps = myTimestampsCache.get(file); + if (timestamps == null) { + synchronized (myTimestampsCache) { // avoid synchroneous reads TODO: + timestamps = myTimestampsCache.get(file); + if (timestamps == null) { + final DataInputStream stream = Timestamps.PERSISTENCE.readAttribute(file); + try { + timestamps = new Timestamps(stream); + } + catch (IOException e) { + throw new RuntimeException(e); + } + myTimestampsCache.put(file, timestamps); + } + } + } + return timestamps; + } + return null; + } + + public static void update(final VirtualFile file, final ID indexName, final long indexCreationStamp) { + synchronized (file) { + try { + Timestamps stamp = createOrGetTimeStamp(file); + if (stamp != null) stamp.set(indexName, indexCreationStamp); + } + catch (InvalidVirtualFileAccessException ignored /*ok to ignore it here*/) { + } + } + } + + public static void flushCache(@Nullable VirtualFile finishedFile) { + if (finishedFile == null || !myFinishedFiles.offer(finishedFile)) { + VirtualFile[] files = null; + synchronized (myFinishedFiles) { + int size = myFinishedFiles.size(); + if ((finishedFile == null && size > 0) || size == CAPACITY) { + files = myFinishedFiles.toArray(new VirtualFile[size]); + myFinishedFiles.clear(); + } + } + + if (files != null) { + for(VirtualFile file:files) { + synchronized (file) { + Timestamps timestamp = myTimestampsCache.remove(file); + if (timestamp == null) continue; + synchronized (myTimestampsCache) { + try { + if (timestamp.isDirty() && file.isValid()) { + final DataOutputStream sink = Timestamps.PERSISTENCE.writeAttribute(file); + timestamp.writeToStream(sink); + sink.close(); + } + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + } + } + } + if (finishedFile != null) myFinishedFiles.offer(finishedFile); + } + } +} diff --git a/platform/lang-impl/src/com/intellij/util/ui/tree/AbstractFileTreeTable.java b/platform/lang-impl/src/com/intellij/util/ui/tree/AbstractFileTreeTable.java index ec32b3994d56..06e833173d78 100644 --- a/platform/lang-impl/src/com/intellij/util/ui/tree/AbstractFileTreeTable.java +++ b/platform/lang-impl/src/com/intellij/util/ui/tree/AbstractFileTreeTable.java @@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileFilter; @@ -212,7 +213,7 @@ public abstract class AbstractFileTreeTable extends TreeTable { TreeNode child = root.getChildAt(i); VirtualFile file = ((FileNode)child).getObject(); if (VfsUtil.isAncestor(file, toSelect, false)) { - if (file == toSelect) { + if (Comparing.equal(file, toSelect)) { TreeUtil.selectNode(getTree(), child); getSelectionModel().clearSelection(); addSelectedPath(TreeUtil.getPathFromRoot(child)); diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/IdeaGateway.java b/platform/lvcs-impl/src/com/intellij/history/integration/IdeaGateway.java index 4b13d2a3929c..18308cb9e751 100644 --- a/platform/lvcs-impl/src/com/intellij/history/integration/IdeaGateway.java +++ b/platform/lvcs-impl/src/com/intellij/history/integration/IdeaGateway.java @@ -32,6 +32,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Clock; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.*; @@ -60,7 +61,7 @@ public class IdeaGateway { for (Project each : openProjects) { if (each.isDefault()) continue; if (!each.isInitialized()) continue; - if (each.getWorkspaceFile() == f) return false; + if (Comparing.equal(each.getWorkspaceFile(), f)) return false; if (ProjectRootManager.getInstance(each).getFileIndex().isIgnored(f)) return false; } diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/revertion/UndoChangeRevertingVisitor.java b/platform/lvcs-impl/src/com/intellij/history/integration/revertion/UndoChangeRevertingVisitor.java index 8c6a3c7cdb78..3d2edf2f2988 100644 --- a/platform/lvcs-impl/src/com/intellij/history/integration/revertion/UndoChangeRevertingVisitor.java +++ b/platform/lvcs-impl/src/com/intellij/history/integration/revertion/UndoChangeRevertingVisitor.java @@ -25,6 +25,7 @@ import com.intellij.history.integration.IdeaGateway; import com.intellij.openapi.command.impl.DocumentUndoProvider; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.HashSet; @@ -101,7 +102,7 @@ public class UndoChangeRevertingVisitor extends ChangeVisitor { if (f != null) { VirtualFile existing = f.getParent().findChild(c.getOldName()); try { - if (existing != null && existing != f) { + if (existing != null && !Comparing.equal(existing, f)) { existing.delete(LocalHistory.VFS_EVENT_REQUESTOR); } f.rename(LocalHistory.VFS_EVENT_REQUESTOR, c.getOldName()); diff --git a/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java b/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java index 331b18d35770..96826cd917de 100644 --- a/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java +++ b/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java @@ -22,6 +22,7 @@ import com.intellij.openapi.editor.event.DocumentAdapter; import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.openapi.vfs.VirtualFile; @@ -53,7 +54,7 @@ public class LazyRangeMarkerFactory extends AbstractProjectComponent { List markers = lazyMarkers.toStrongList(); List markersToRemove = new ArrayList(); for (final LazyMarker marker : markers) { - if (marker.getFile() == docFile) { + if (Comparing.equal(marker.getFile(), docFile)) { marker.ensureDelegate(); markersToRemove.add(marker); } diff --git a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileElement.java b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileElement.java index 8e61b7327f80..6b15e4a3dad7 100644 --- a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileElement.java +++ b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileElement.java @@ -16,6 +16,7 @@ package com.intellij.openapi.fileChooser; import com.intellij.openapi.fileTypes.FileTypes; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.StringBuilderSpinAllocator; @@ -84,7 +85,7 @@ public class FileElement { @Override public boolean equals(Object obj) { if (obj instanceof FileElement) { - if (((FileElement)obj).myFile == myFile) return true; + if (Comparing.equal(((FileElement)obj).myFile, myFile)) return true; } return false; } diff --git a/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java b/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java index 78464b10d14a..c15570283dae 100644 --- a/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java +++ b/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java @@ -1,264 +1,265 @@ -/* - * Copyright 2000-2009 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.fileEditor; - -import com.intellij.ide.*; -import com.intellij.ide.FileEditorProvider; -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.DataKey; -import com.intellij.openapi.editor.*; -import com.intellij.openapi.fileTypes.FileType; -import com.intellij.openapi.fileTypes.FileTypeManager; -import com.intellij.openapi.fileTypes.INativeFileType; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.wm.IdeFocusManager; -import com.intellij.pom.Navigatable; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -public class OpenFileDescriptor implements Navigatable { - /** - * Tells descriptor to navigate in specific editor rather than file editor - * in main IDEA window. - * For example if you want to navigate in editor embedded into modal dialog, - * you should provide this data. - */ - public static final DataKey NAVIGATE_IN_EDITOR = DataKey.create("NAVIGATE_IN_EDITOR"); - - @NotNull - private final VirtualFile myFile; - private final int myOffset; - private final int myLogicalLine; - private final int myLogicalColumn; - private final RangeMarker myRangeMarker; - @NotNull - private final Project myProject; - - private boolean myUseCurrentWindow = false; - - public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, int offset) { - this(project, file, -1, -1, offset, false); - } - - public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, int logicalLine, int logicalColumn) { - this(project, file, logicalLine, logicalColumn, -1, false); - } - - public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, - int logicalLine, int logicalColumn, boolean persistent) { - this(project, file, logicalLine, logicalColumn, -1, persistent); - } - - public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file) { - this(project, file, -1, -1, -1, false); - } - - private OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, - int logicalLine, int logicalColumn, int offset, boolean persistent) { - myProject = project; - - myFile = file; - myLogicalLine = logicalLine; - myLogicalColumn = logicalColumn; - myOffset = offset; - if (offset >= 0) { - myRangeMarker = LazyRangeMarkerFactory.getInstance(project).createRangeMarker(file, offset); - } - else if (logicalLine >= 0 ){ - myRangeMarker = LazyRangeMarkerFactory.getInstance(project).createRangeMarker(file, logicalLine, Math.max(0, logicalColumn), persistent); - } - else { - myRangeMarker = null; - } - } - - @NotNull - public VirtualFile getFile() { - return myFile; - } - - @Nullable - public RangeMarker getRangeMarker() { - return myRangeMarker; - } - - public int getOffset() { - return myRangeMarker != null && myRangeMarker.isValid() ? myRangeMarker.getStartOffset() : myOffset; - } - - public int getLine() { - return myLogicalLine; - } - - public int getColumn() { - return myLogicalColumn; - } - - @Override - public void navigate(boolean requestFocus) { - if (!canNavigate()) { - throw new IllegalStateException("Navigation is not possible with null project"); - } - - if (!myFile.isDirectory() && navigateInEditor(myProject, requestFocus)) return; - - navigateInProjectView(); - } - - private boolean navigateInEditor(@NotNull Project project, boolean requestFocus) { - FileType type = FileTypeManager.getInstance().getKnownFileTypeOrAssociate(myFile,project); - if (type == null || !myFile.isValid()) return false; - - if (type instanceof INativeFileType) { - return ((INativeFileType) type).openFileInAssociatedApplication(project, myFile); - } - - return navigateInRequestedEditor() || navigateInAnyFileEditor(project, requestFocus); - } - - private boolean navigateInRequestedEditor() { - DataContext ctx = DataManager.getInstance().getDataContext(); - Editor e = NAVIGATE_IN_EDITOR.getData(ctx); - if (e == null) return false; - if (FileDocumentManager.getInstance().getFile(e.getDocument()) != myFile) return false; - - navigateIn(e); - return true; - } - - private boolean navigateInAnyFileEditor(Project project, boolean focusEditor) { - List editors = FileEditorManager.getInstance(project).openEditor(this, focusEditor); - for (FileEditor editor : editors) { - if (editor instanceof TextEditor) { - Editor e = ((TextEditor)editor).getEditor(); - unfoldCurrentLine(e); - if (focusEditor) { - IdeFocusManager.getInstance(myProject).requestFocus(e.getContentComponent(), true); - } - } - } - return !editors.isEmpty(); - } - - private void navigateInProjectView() { - SelectInContext context = new SelectInContext() { - @Override - @NotNull - public Project getProject() { - return myProject; - } - - @Override - @NotNull - public VirtualFile getVirtualFile() { - return myFile; - } - - @Override - @Nullable - public Object getSelectorInFile() { - return null; - } - - @Override - @Nullable - public FileEditorProvider getFileEditorProvider() { - return null; - } - }; - - for (SelectInTarget target : SelectInManager.getInstance(myProject).getTargets()) { - if (target.canSelect(context)) { - target.selectIn(context, true); - return; - } - } - } - - public void navigateIn(@NotNull Editor e) { - final int offset = getOffset(); - CaretModel caretModel = e.getCaretModel(); - boolean caretMoved = false; - if (myLogicalLine >= 0) { - LogicalPosition pos = new LogicalPosition(myLogicalLine, Math.max(myLogicalColumn, 0)); - if (offset < 0 || offset == e.logicalPositionToOffset(pos)) { - caretModel.moveToLogicalPosition(pos); - caretMoved = true; - } - } - if (!caretMoved && offset >= 0) { - caretModel.moveToOffset(Math.min(offset, e.getDocument().getTextLength())); - caretMoved = true; - } - - if (caretMoved) { - e.getSelectionModel().removeSelection(); - scrollToCaret(e); - unfoldCurrentLine(e); - } - } - - private static void unfoldCurrentLine(@NotNull final Editor editor) { - final FoldRegion[] allRegions = editor.getFoldingModel().getAllFoldRegions(); - final int offset = editor.getCaretModel().getOffset(); - int line = editor.getDocument().getLineNumber(offset); - int start = editor.getDocument().getLineStartOffset(line); - int end = editor.getDocument().getLineEndOffset(line); - final TextRange range = new TextRange(start, end); - editor.getFoldingModel().runBatchFoldingOperation(new Runnable() { - @Override - public void run() { - for (FoldRegion region : allRegions) { - if (!region.isExpanded() && range.intersects(TextRange.create(region))) { - region.setExpanded(true); - } - } - } - }); - } - - private static void scrollToCaret(@NotNull Editor e) { - e.getScrollingModel().scrollToCaret(ScrollType.CENTER); - } - - @Override - public boolean canNavigate() { - return myFile.isValid(); - } - - @Override - public boolean canNavigateToSource() { - return canNavigate(); - } - - @NotNull - public Project getProject() { - return myProject; - } - - public OpenFileDescriptor setUseCurrentWindow(boolean search) { - myUseCurrentWindow = search; - return this; - } - - public boolean isUseCurrentWindow() { - return myUseCurrentWindow; - } -} +/* + * Copyright 2000-2009 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.fileEditor; + +import com.intellij.ide.*; +import com.intellij.ide.FileEditorProvider; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.DataKey; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.INativeFileType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.pom.Navigatable; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class OpenFileDescriptor implements Navigatable { + /** + * Tells descriptor to navigate in specific editor rather than file editor + * in main IDEA window. + * For example if you want to navigate in editor embedded into modal dialog, + * you should provide this data. + */ + public static final DataKey NAVIGATE_IN_EDITOR = DataKey.create("NAVIGATE_IN_EDITOR"); + + @NotNull + private final VirtualFile myFile; + private final int myOffset; + private final int myLogicalLine; + private final int myLogicalColumn; + private final RangeMarker myRangeMarker; + @NotNull + private final Project myProject; + + private boolean myUseCurrentWindow = false; + + public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, int offset) { + this(project, file, -1, -1, offset, false); + } + + public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, int logicalLine, int logicalColumn) { + this(project, file, logicalLine, logicalColumn, -1, false); + } + + public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, + int logicalLine, int logicalColumn, boolean persistent) { + this(project, file, logicalLine, logicalColumn, -1, persistent); + } + + public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file) { + this(project, file, -1, -1, -1, false); + } + + private OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, + int logicalLine, int logicalColumn, int offset, boolean persistent) { + myProject = project; + + myFile = file; + myLogicalLine = logicalLine; + myLogicalColumn = logicalColumn; + myOffset = offset; + if (offset >= 0) { + myRangeMarker = LazyRangeMarkerFactory.getInstance(project).createRangeMarker(file, offset); + } + else if (logicalLine >= 0 ){ + myRangeMarker = LazyRangeMarkerFactory.getInstance(project).createRangeMarker(file, logicalLine, Math.max(0, logicalColumn), persistent); + } + else { + myRangeMarker = null; + } + } + + @NotNull + public VirtualFile getFile() { + return myFile; + } + + @Nullable + public RangeMarker getRangeMarker() { + return myRangeMarker; + } + + public int getOffset() { + return myRangeMarker != null && myRangeMarker.isValid() ? myRangeMarker.getStartOffset() : myOffset; + } + + public int getLine() { + return myLogicalLine; + } + + public int getColumn() { + return myLogicalColumn; + } + + @Override + public void navigate(boolean requestFocus) { + if (!canNavigate()) { + throw new IllegalStateException("Navigation is not possible with null project"); + } + + if (!myFile.isDirectory() && navigateInEditor(myProject, requestFocus)) return; + + navigateInProjectView(); + } + + private boolean navigateInEditor(@NotNull Project project, boolean requestFocus) { + FileType type = FileTypeManager.getInstance().getKnownFileTypeOrAssociate(myFile,project); + if (type == null || !myFile.isValid()) return false; + + if (type instanceof INativeFileType) { + return ((INativeFileType) type).openFileInAssociatedApplication(project, myFile); + } + + return navigateInRequestedEditor() || navigateInAnyFileEditor(project, requestFocus); + } + + private boolean navigateInRequestedEditor() { + DataContext ctx = DataManager.getInstance().getDataContext(); + Editor e = NAVIGATE_IN_EDITOR.getData(ctx); + if (e == null) return false; + if (!Comparing.equal(FileDocumentManager.getInstance().getFile(e.getDocument()), myFile)) return false; + + navigateIn(e); + return true; + } + + private boolean navigateInAnyFileEditor(Project project, boolean focusEditor) { + List editors = FileEditorManager.getInstance(project).openEditor(this, focusEditor); + for (FileEditor editor : editors) { + if (editor instanceof TextEditor) { + Editor e = ((TextEditor)editor).getEditor(); + unfoldCurrentLine(e); + if (focusEditor) { + IdeFocusManager.getInstance(myProject).requestFocus(e.getContentComponent(), true); + } + } + } + return !editors.isEmpty(); + } + + private void navigateInProjectView() { + SelectInContext context = new SelectInContext() { + @Override + @NotNull + public Project getProject() { + return myProject; + } + + @Override + @NotNull + public VirtualFile getVirtualFile() { + return myFile; + } + + @Override + @Nullable + public Object getSelectorInFile() { + return null; + } + + @Override + @Nullable + public FileEditorProvider getFileEditorProvider() { + return null; + } + }; + + for (SelectInTarget target : SelectInManager.getInstance(myProject).getTargets()) { + if (target.canSelect(context)) { + target.selectIn(context, true); + return; + } + } + } + + public void navigateIn(@NotNull Editor e) { + final int offset = getOffset(); + CaretModel caretModel = e.getCaretModel(); + boolean caretMoved = false; + if (myLogicalLine >= 0) { + LogicalPosition pos = new LogicalPosition(myLogicalLine, Math.max(myLogicalColumn, 0)); + if (offset < 0 || offset == e.logicalPositionToOffset(pos)) { + caretModel.moveToLogicalPosition(pos); + caretMoved = true; + } + } + if (!caretMoved && offset >= 0) { + caretModel.moveToOffset(Math.min(offset, e.getDocument().getTextLength())); + caretMoved = true; + } + + if (caretMoved) { + e.getSelectionModel().removeSelection(); + scrollToCaret(e); + unfoldCurrentLine(e); + } + } + + private static void unfoldCurrentLine(@NotNull final Editor editor) { + final FoldRegion[] allRegions = editor.getFoldingModel().getAllFoldRegions(); + final int offset = editor.getCaretModel().getOffset(); + int line = editor.getDocument().getLineNumber(offset); + int start = editor.getDocument().getLineStartOffset(line); + int end = editor.getDocument().getLineEndOffset(line); + final TextRange range = new TextRange(start, end); + editor.getFoldingModel().runBatchFoldingOperation(new Runnable() { + @Override + public void run() { + for (FoldRegion region : allRegions) { + if (!region.isExpanded() && range.intersects(TextRange.create(region))) { + region.setExpanded(true); + } + } + } + }); + } + + private static void scrollToCaret(@NotNull Editor e) { + e.getScrollingModel().scrollToCaret(ScrollType.CENTER); + } + + @Override + public boolean canNavigate() { + return myFile.isValid(); + } + + @Override + public boolean canNavigateToSource() { + return canNavigate(); + } + + @NotNull + public Project getProject() { + return myProject; + } + + public OpenFileDescriptor setUseCurrentWindow(boolean search) { + myUseCurrentWindow = search; + return this; + } + + public boolean isUseCurrentWindow() { + return myUseCurrentWindow; + } +} diff --git a/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java b/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java index 38675fe45e03..08dbaeb3e653 100644 --- a/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java +++ b/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java @@ -20,6 +20,7 @@ import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.fileTypes.FileTypes; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; @@ -327,6 +328,16 @@ public class VfsUtil extends VfsUtilCore { return virtualFileManager.findFileByUrl(vfUrl); } + @Nullable + public static VirtualFile findFileByIoFile(@NotNull File file, boolean refreshIfNeeded) { + LocalFileSystem fileSystem = LocalFileSystem.getInstance(); + VirtualFile virtualFile = fileSystem.findFileByIoFile(file); + if (virtualFile == null && refreshIfNeeded) { + virtualFile = fileSystem.refreshAndFindFileByIoFile(file); + } + return virtualFile; + } + /** * Converts VsfUrl info java.net.URL. Does not support "jar:" protocol. * @@ -473,8 +484,8 @@ public class VfsUtil extends VfsUtilCore { final VirtualFile commonAncestor = getCommonAncestor(src, dst); if (commonAncestor != null) { StringBuilder buffer = new StringBuilder(); - if (src != commonAncestor) { - while (src.getParent() != commonAncestor) { + if (!Comparing.equal(src, commonAncestor)) { + while (!Comparing.equal(src.getParent(), commonAncestor)) { buffer.append("..").append(separatorChar); src = src.getParent(); } diff --git a/platform/platform-api/src/com/intellij/ui/RowsDnDSupport.java b/platform/platform-api/src/com/intellij/ui/RowsDnDSupport.java index 1a8438cc511e..a29c73739737 100644 --- a/platform/platform-api/src/com/intellij/ui/RowsDnDSupport.java +++ b/platform/platform-api/src/com/intellij/ui/RowsDnDSupport.java @@ -47,6 +47,7 @@ public class RowsDnDSupport { } private static void installImpl(@NotNull final JComponent component, @NotNull final EditableModel model) { + component.setTransferHandler(new TransferHandler(null)); DnDSupport.createBuilder(component) .setBeanProvider(new Function() { @Override @@ -72,8 +73,10 @@ public class RowsDnDSupport { event.setHighlighting(rectangle, 2); } else { - event.setDropPossible(false); + if (oldIndex != newIndex) // Drag&Drop always starts with new==old and we shouldn't display 'rejecting' cursor in this case + event.setDropPossible(false, ""); event.hideHighlighter(); + return true; } return false; } @@ -122,7 +125,7 @@ public class RowsDnDSupport { } else if (component instanceof JList) { return ((JList)component).locationToIndex(point); } else if (component instanceof JTree) { - return ((JTree)component).getRowForLocation(point.x, point.y); + return ((JTree)component).getClosestRowForLocation(point.x, point.y); } else { throw new IllegalArgumentException("Unsupported component: " + component); } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CloseAllEditorsButActiveAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CloseAllEditorsButActiveAction.java index 443a10030ec2..683e205d644e 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/CloseAllEditorsButActiveAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/CloseAllEditorsButActiveAction.java @@ -1,4 +1,3 @@ - /* * Copyright 2000-2009 JetBrains s.r.o. * @@ -24,6 +23,7 @@ import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; import com.intellij.openapi.fileEditor.impl.EditorWindow; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VirtualFile; public class CloseAllEditorsButActiveAction extends AnAction implements DumbAware { @@ -39,7 +39,7 @@ public class CloseAllEditorsButActiveAction extends AnAction implements DumbAwar selectedFile = fileEditorManager.getSelectedFiles()[0]; final VirtualFile[] siblings = fileEditorManager.getSiblings(selectedFile); for (final VirtualFile sibling : siblings) { - if (selectedFile != sibling) { + if (!Comparing.equal(selectedFile, sibling)) { fileEditorManager.closeFile(sibling); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandMerger.java b/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandMerger.java index a5b968468de0..ca9103d60b1a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandMerger.java +++ b/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandMerger.java @@ -231,6 +231,14 @@ public class CommandMerger { return !myCurrentActions.isEmpty(); } + public boolean isPhysical() { + if (myAllAffectedDocuments.isEmpty()) return false; + for (DocumentReference each : myAllAffectedDocuments) { + if (each.getFile() == null) return false; + } + return true; + } + public boolean isUndoAvailable(@NotNull Collection refs) { if (hasNonUndoableActions()) { return false; diff --git a/platform/platform-impl/src/com/intellij/openapi/command/impl/DocumentReferenceManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/command/impl/DocumentReferenceManagerImpl.java index a53830f241b7..c5405f1e9dc3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/command/impl/DocumentReferenceManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/command/impl/DocumentReferenceManagerImpl.java @@ -21,6 +21,7 @@ import com.intellij.openapi.command.undo.DocumentReferenceManager; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Key; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileAdapter; @@ -75,7 +76,7 @@ public class DocumentReferenceManagerImpl extends DocumentReferenceManager imple List files = f.getUserData(DELETED_FILES); f.putUserData(DELETED_FILES, null); - assert files != null; + assert files != null : f; for (VirtualFile each : files) { Reference r = new WeakReferenceWithEquals(each); DocumentReference ref = myFileToRef.remove(r); @@ -159,7 +160,7 @@ public class DocumentReferenceManagerImpl extends DocumentReferenceManager imple @Override public boolean equals(Object obj) { T doc = get(); - return doc != null && obj instanceof Reference && ((Reference)obj).get() == doc; + return doc != null && obj instanceof Reference && Comparing.equal(doc, ((Reference)obj).get()); } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java index 8dfe6ea8cfed..b412d811ea4d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java @@ -283,7 +283,7 @@ public class UndoManagerImpl extends UndoManager implements ProjectComponent, Ap myCommandLevel--; if (myCommandLevel > 0) return; - if (myProject != null && myCurrentMerger.hasActions() && !myCurrentMerger.isTransparent()) { + if (myProject != null && myCurrentMerger.hasActions() && !myCurrentMerger.isTransparent() && myCurrentMerger.isPhysical()) { addFocusedDocumentAsAffected(); } myOriginatorReference = null; diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java index 33c8e1d104b5..bedb82bbca22 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java @@ -181,7 +181,7 @@ public abstract class EditorComposite implements Disposable { public void selectionChanged(final FileEditorManagerEvent event) { final VirtualFile oldFile = event.getOldFile(); final VirtualFile newFile = event.getNewFile(); - if (oldFile == newFile && getFile() == newFile) { + if (Comparing.equal(oldFile, newFile) && Comparing.equal(getFile(), newFile)) { final FileEditor oldEditor = event.getOldEditor(); if (oldEditor != null) oldEditor.deselectNotify(); final FileEditor newEditor = event.getNewEditor(); diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java index 03791c9477d5..5380ee9ec8fa 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java @@ -26,6 +26,7 @@ import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.DumbAwareRunnable; import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.JDOMExternalizable; import com.intellij.openapi.util.Pair; @@ -254,7 +255,7 @@ public final class EditorHistoryManager extends AbstractProjectComponent impleme public boolean hasBeenOpen(@NotNull VirtualFile f) { for (HistoryEntry each : myEntriesList) { - if (each.myFile == f) return true; + if (Comparing.equal(each.myFile, f)) return true; } return false; } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java index c1cfae48f8ee..81d51d770538 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java @@ -122,7 +122,7 @@ public class EditorWindow { public void closeAllExcept(final VirtualFile selectedFile) { final VirtualFile[] files = getFiles(); for (final VirtualFile file : files) { - if (file != selectedFile && !isFilePinned(file)) { + if (!Comparing.equal(file, selectedFile) && !isFilePinned(file)) { closeFile(file); } } @@ -1090,7 +1090,7 @@ public class EditorWindow { if (fileCanBeClosed(file, fileToIgnore)) { boolean found = false; for (int j = 0; j != histFiles.length; j++) { - if (histFiles[j] == file) { + if (Comparing.equal(histFiles[j], file)) { found = true; break; } @@ -1146,7 +1146,7 @@ public class EditorWindow { if (fileCanBeClosed(file, fileToIgnore)) { boolean found = false; for (int j = 0; j != histFiles.length; j++) { - if (histFiles[j] == file) { + if (Comparing.equal(histFiles[j], file)) { found = true; break; } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java index e5c2c5eb7991..1afc02766e6b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java @@ -387,7 +387,7 @@ public class EditorsSplitters extends JPanel { final VirtualFile currentFile = getCurrentFile(); if (currentFile != null) { for (int i = 0; i != virtualFiles.length; ++i) { - if (virtualFiles[i] == currentFile) { + if (Comparing.equal(virtualFiles[i], currentFile)) { virtualFiles[i] = virtualFiles[0]; virtualFiles[0] = currentFile; break; @@ -572,7 +572,7 @@ public class EditorsSplitters extends JPanel { for (int i = 0; i != windows.length; ++i) { final VirtualFile[] files = windows[i].getFiles(); for (final VirtualFile fileAt : files) { - if (fileAt != file) { + if (!Comparing.equal(fileAt, file)) { return fileAt; } } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java index a12860e54b64..a050a9455940 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java @@ -1,1801 +1,1801 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.openapi.fileEditor.impl; - -import com.intellij.ProjectTopics; -import com.intellij.ide.IdeBundle; -import com.intellij.ide.plugins.PluginManager; -import com.intellij.ide.ui.UISettings; -import com.intellij.ide.ui.UISettingsListener; -import com.intellij.injected.editor.VirtualFileWindow; -import com.intellij.openapi.Disposable; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ModalityState; -import com.intellij.openapi.application.ex.ApplicationManagerEx; -import com.intellij.openapi.application.impl.LaterInvocator; -import com.intellij.openapi.command.CommandProcessor; -import com.intellij.openapi.components.ProjectComponent; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.ScrollType; -import com.intellij.openapi.editor.ex.EditorEx; -import com.intellij.openapi.editor.impl.EditorComponentImpl; -import com.intellij.openapi.extensions.Extensions; -import com.intellij.openapi.fileEditor.*; -import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; -import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager; -import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; -import com.intellij.openapi.fileEditor.impl.text.TextEditorImpl; -import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider; -import com.intellij.openapi.fileTypes.FileTypeEvent; -import com.intellij.openapi.fileTypes.FileTypeListener; -import com.intellij.openapi.fileTypes.FileTypeManager; -import com.intellij.openapi.project.DumbAwareRunnable; -import com.intellij.openapi.project.DumbService; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.impl.ProjectImpl; -import com.intellij.openapi.roots.ModuleRootAdapter; -import com.intellij.openapi.roots.ModuleRootEvent; -import com.intellij.openapi.startup.StartupManager; -import com.intellij.openapi.util.*; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.util.registry.Registry; -import com.intellij.openapi.vcs.FileStatus; -import com.intellij.openapi.vcs.FileStatusListener; -import com.intellij.openapi.vcs.FileStatusManager; -import com.intellij.openapi.vfs.*; -import com.intellij.openapi.wm.IdeFocusManager; -import com.intellij.openapi.wm.ToolWindowManager; -import com.intellij.openapi.wm.WindowManager; -import com.intellij.openapi.wm.ex.StatusBarEx; -import com.intellij.openapi.wm.impl.IdeFrameImpl; -import com.intellij.ui.FocusTrackback; -import com.intellij.ui.docking.DockContainer; -import com.intellij.ui.docking.DockManager; -import com.intellij.ui.tabs.impl.JBTabsImpl; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.messages.MessageBusConnection; -import com.intellij.util.messages.impl.MessageListenerList; -import com.intellij.util.ui.SameColor; -import com.intellij.util.ui.UIUtil; -import com.intellij.util.ui.update.MergingUpdateQueue; -import com.intellij.util.ui.update.Update; -import org.jdom.Element; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; -import javax.swing.border.Border; -import java.awt.*; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.lang.ref.WeakReference; -import java.util.*; -import java.util.List; - -/** - * @author Anton Katilin - * @author Eugene Belyaev - * @author Vladimir Kondratyev - */ -public class FileEditorManagerImpl extends FileEditorManagerEx implements ProjectComponent, JDOMExternalizable { - private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl"); - private static final Key WATCH_REQUEST_KEY = Key.create("WATCH_REQUEST_KEY"); - private static final Key DUMB_AWARE = Key.create("DUMB_AWARE"); - - private static final FileEditor[] EMPTY_EDITOR_ARRAY = {}; - private static final FileEditorProvider[] EMPTY_PROVIDER_ARRAY = {}; - public static final Key CLOSING_TO_REOPEN = Key.create("CLOSING_TO_REOPEN"); - - private volatile JPanel myPanels; - private EditorsSplitters mySplitters; - private final Project myProject; - private final List> mySelectionHistory = new ArrayList>(); - private WeakReference myLastSelectedComposite = new WeakReference(null); - - - private final MergingUpdateQueue myQueue = new MergingUpdateQueue("FileEditorManagerUpdateQueue", 50, true, null); - - private final BusyObject.Impl.Simple myBusyObject = new BusyObject.Impl.Simple(); - - /** - * Removes invalid myEditor and updates "modified" status. - */ - private final MyEditorPropertyChangeListener myEditorPropertyChangeListener = new MyEditorPropertyChangeListener(); - private final DockManager myDockManager; - private DockableEditorContainerFactory myContentFactory; - - public FileEditorManagerImpl(final Project project, DockManager dockManager) { -/* ApplicationManager.getApplication().assertIsDispatchThread(); */ - myProject = project; - myDockManager = dockManager; - myListenerList = - new MessageListenerList(myProject.getMessageBus(), FileEditorManagerListener.FILE_EDITOR_MANAGER); - - if (Extensions.getExtensions(FileEditorAssociateFinder.EP_NAME).length > 0) { - myListenerList.add(new FileEditorManagerAdapter() { - @Override - public void selectionChanged(FileEditorManagerEvent event) { - EditorsSplitters splitters = getSplitters(); - openAssociatedFile(event.getNewFile(), splitters.getCurrentWindow(), splitters); - } - }); - } - - myQueue.setTrackUiActivity(true); - } - - void initDockableContentFactory() { - if (myContentFactory != null) return; - - myContentFactory = new DockableEditorContainerFactory(myProject, this, myDockManager); - myDockManager.register(DockableEditorContainerFactory.TYPE, myContentFactory); - Disposer.register(myProject, myContentFactory); - } - - public static boolean isDumbAware(FileEditor editor) { - return Boolean.TRUE.equals(editor.getUserData(DUMB_AWARE)); - } - - //------------------------------------------------------------------------------- - - public JComponent getComponent() { - initUI(); - return myPanels; - } - - public EditorsSplitters getMainSplitters() { - initUI(); - - return mySplitters; - } - - public Set getAllSplitters() { - HashSet all = new HashSet(); - all.add(getMainSplitters()); - Set dockContainers = myDockManager.getContainers(); - for (DockContainer each : dockContainers) { - if (each instanceof DockableEditorTabbedContainer) { - all.add(((DockableEditorTabbedContainer)each).getSplitters()); - } - } - - return Collections.unmodifiableSet(all); - } - - private AsyncResult getActiveSplitters(boolean syncUsage) { - final boolean async = Registry.is("ide.windowSystem.asyncSplitters") && !syncUsage; - - final AsyncResult result = new AsyncResult(); - final IdeFocusManager fm = IdeFocusManager.getInstance(myProject); - Runnable run = new Runnable() { - @Override - public void run() { - if (myProject.isDisposed()) { - result.setRejected(); - return; - } - - Component focusOwner = fm.getFocusOwner(); - if (focusOwner == null && !async) { - focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); - } - - if (focusOwner == null && !async) { - focusOwner = fm.getLastFocusedFor(fm.getLastFocusedFrame()); - } - - DockContainer container = myDockManager.getContainerFor(focusOwner); - if (container == null && !async) { - focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow(); - container = myDockManager.getContainerFor(focusOwner); - } - - if (container instanceof DockableEditorTabbedContainer) { - result.setDone(((DockableEditorTabbedContainer)container).getSplitters()); - } - else { - result.setDone(getMainSplitters()); - } - } - }; - - if (async) { - fm.doWhenFocusSettlesDown(run); - } - else { - run.run(); - } - - return result; - } - - private final Object myInitLock = new Object(); - - private void initUI() { - if (myPanels == null) { - synchronized (myInitLock) { - if (myPanels == null) { - myPanels = new JPanel(new BorderLayout()) { - @Override - public Color getBackground() { - boolean navBar = UISettings.getInstance().SHOW_NAVIGATION_BAR; - if (navBar) { - return UIUtil.getSlightlyDarkerColor(UIUtil.isUnderAquaLookAndFeel() ? new SameColor(200) : UIUtil.getPanelBackground()); - } else { - return UIUtil.isUnderAquaLookAndFeel() ? new SameColor(189) : UIUtil.getPanelBackground(); - } - } - }; - myPanels.setBorder(new MyBorder()); - mySplitters = new EditorsSplitters(this, myDockManager, true); - myPanels.add(mySplitters, BorderLayout.CENTER); - } - } - } - } - - private static class MyBorder implements Border { - @Override - public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { - if (UIUtil.isUnderAquaLookAndFeel()) { - g.setColor(JBTabsImpl.MAC_AQUA_BG_COLOR); - final Insets insets = getBorderInsets(c); - if (insets.top > 0) { - g.fillRect(x, y, width, height + insets.top); - } - } - } - - @Override - public Insets getBorderInsets(Component c) { - return new Insets(0, 0, 0, 0); - } - - @Override - public boolean isBorderOpaque() { - return false; - } - } - - public JComponent getPreferredFocusedComponent() { - assertReadAccess(); - final EditorWindow window = getSplitters().getCurrentWindow(); - if (window != null) { - final EditorWithProviderComposite editor = window.getSelectedEditor(); - if (editor != null) { - return editor.getPreferredFocusedComponent(); - } - } - return null; - } - - //------------------------------------------------------- - - /** - * @return color of the file which corresponds to the - * file's status - */ - public Color getFileColor(@NotNull final VirtualFile file) { - final FileStatusManager fileStatusManager = FileStatusManager.getInstance(myProject); - Color statusColor = fileStatusManager != null ? fileStatusManager.getStatus(file).getColor() : Color.BLACK; - if (statusColor == null) statusColor = Color.BLACK; - return statusColor; - } - - public boolean isProblem(@NotNull final VirtualFile file) { - return false; - } - - public String getFileTooltipText(VirtualFile file) { - return FileUtil.getLocationRelativeToUserHome(file.getPresentableUrl()); - } - - public void updateFilePresentation(VirtualFile file) { - if (!isFileOpen(file)) return; - - updateFileColor(file); - updateFileIcon(file); - updateFileName(file); - updateFileBackgroundColor(file); - } - - /** - * Updates tab color for the specified file. The file - * should be opened in the myEditor, otherwise the method throws an assertion. - */ - private void updateFileColor(final VirtualFile file) { - Set all = getAllSplitters(); - for (EditorsSplitters each : all) { - each.updateFileColor(file); - } - } - - private void updateFileBackgroundColor(final VirtualFile file) { - Set all = getAllSplitters(); - for (EditorsSplitters each : all) { - each.updateFileBackgroundColor(file); - } - } - - /** - * Updates tab icon for the specified file. The file - * should be opened in the myEditor, otherwise the method throws an assertion. - */ - protected void updateFileIcon(final VirtualFile file) { - Set all = getAllSplitters(); - for (EditorsSplitters each : all) { - each.updateFileIcon(file); - } - } - - /** - * Updates tab title and tab tool tip for the specified file - */ - void updateFileName(@Nullable final VirtualFile file) { - // Queue here is to prevent title flickering when tab is being closed and two events arriving: with component==null and component==next focused tab - // only the last event makes sense to handle - myQueue.queue(new Update("UpdateFileName " + (file == null ? "" : file.getPath())) { - public boolean isExpired() { - return myProject.isDisposed() || !myProject.isOpen() || (file == null ? super.isExpired() : !file.isValid()); - } - - public void run() { - Set all = getAllSplitters(); - for (EditorsSplitters each : all) { - each.updateFileName(file); - } - } - }); - } - - //------------------------------------------------------- - - - public VirtualFile getFile(@NotNull final FileEditor editor) { - final EditorComposite editorComposite = getEditorComposite(editor); - if (editorComposite != null) { - return editorComposite.getFile(); - } - return null; - } - - public void unsplitWindow() { - final EditorWindow currentWindow = getActiveSplitters(true).getResult().getCurrentWindow(); - if (currentWindow != null) { - currentWindow.unsplit(true); - } - } - - public void unsplitAllWindow() { - final EditorWindow currentWindow = getActiveSplitters(true).getResult().getCurrentWindow(); - if (currentWindow != null) { - currentWindow.unsplitAll(); - } - } - - @Override - public int getWindowSplitCount() { - return getActiveSplitters(true).getResult().getSplitCount(); - } - - @Override - public boolean hasSplitOrUndockedWindows() { - Set splitters = getAllSplitters(); - if (splitters.size() > 1) return true; - return getWindowSplitCount() > 1; - } - - @NotNull - public EditorWindow[] getWindows() { - ArrayList windows = new ArrayList(); - Set all = getAllSplitters(); - for (EditorsSplitters each : all) { - EditorWindow[] eachList = each.getWindows(); - windows.addAll(Arrays.asList(eachList)); - } - - return windows.toArray(new EditorWindow[windows.size()]); - } - - public EditorWindow getNextWindow(@NotNull final EditorWindow window) { - final EditorWindow[] windows = getSplitters().getOrderedWindows(); - for (int i = 0; i != windows.length; ++i) { - if (windows[i].equals(window)) { - return windows[(i + 1) % windows.length]; - } - } - LOG.error("Not window found"); - return null; - } - - public EditorWindow getPrevWindow(@NotNull final EditorWindow window) { - final EditorWindow[] windows = getSplitters().getOrderedWindows(); - for (int i = 0; i != windows.length; ++i) { - if (windows[i].equals(window)) { - return windows[(i + windows.length - 1) % windows.length]; - } - } - LOG.error("Not window found"); - return null; - } - - public void createSplitter(final int orientation, @Nullable final EditorWindow window) { - // window was available from action event, for example when invoked from the tab menu of an editor that is not the 'current' - if (window != null) { - window.split(orientation, true, null, false); - } - // otherwise we'll split the current window, if any - else { - final EditorWindow currentWindow = getSplitters().getCurrentWindow(); - if (currentWindow != null) { - currentWindow.split(orientation, true, null, false); - } - } - } - - public void changeSplitterOrientation() { - final EditorWindow currentWindow = getSplitters().getCurrentWindow(); - if (currentWindow != null) { - currentWindow.changeOrientation(); - } - } - - - public void flipTabs() { - /* - if (myTabs == null) { - myTabs = new EditorTabs (this, UISettings.getInstance().EDITOR_TAB_PLACEMENT); - remove (mySplitters); - add (myTabs, BorderLayout.CENTER); - initTabs (); - } else { - remove (myTabs); - add (mySplitters, BorderLayout.CENTER); - myTabs.dispose (); - myTabs = null; - } - */ - myPanels.revalidate(); - } - - public boolean tabsMode() { - return false; - } - - private void setTabsMode(final boolean mode) { - if (tabsMode() != mode) { - flipTabs(); - } - //LOG.assertTrue (tabsMode () == mode); - } - - - public boolean isInSplitter() { - final EditorWindow currentWindow = getSplitters().getCurrentWindow(); - return currentWindow != null && currentWindow.inSplitter(); - } - - public boolean hasOpenedFile() { - final EditorWindow currentWindow = getSplitters().getCurrentWindow(); - return currentWindow != null && currentWindow.getSelectedEditor() != null; - } - - public VirtualFile getCurrentFile() { - return getActiveSplitters(true).getResult().getCurrentFile(); - } - - public AsyncResult getActiveWindow() { - return _getActiveWindow(false); - } - - private AsyncResult _getActiveWindow(boolean now) { - final AsyncResult result = new AsyncResult(); - getActiveSplitters(now).doWhenDone(new AsyncResult.Handler() { - @Override - public void run(EditorsSplitters editorsSplitters) { - result.setDone(editorsSplitters.getCurrentWindow()); - } - }); - - return result; - } - - public EditorWindow getCurrentWindow() { - return _getActiveWindow(true).getResult(); - } - - public void setCurrentWindow(final EditorWindow window) { - getActiveSplitters(true).getResult().setCurrentWindow(window, true); - } - - public void closeFile(@NotNull final VirtualFile file, @NotNull final EditorWindow window, final boolean transferFocus) { - assertDispatchThread(); - - CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { - public void run() { - if (window.isFileOpen(file)) { - window.closeFile(file, true, transferFocus); - final List windows = window.getOwner().findWindows(file); - if (windows.isEmpty()) { // no more windows containing this file left - final LocalFileSystem.WatchRequest request = file.getUserData(WATCH_REQUEST_KEY); - if (request != null) { - LocalFileSystem.getInstance().removeWatchedRoot(request); - } - } - } - } - }, IdeBundle.message("command.close.active.editor"), null); - removeSelectionRecord(file, window); - } - - public void closeFile(@NotNull final VirtualFile file, @NotNull final EditorWindow window) { - closeFile(file, window, true); - } - - //============================= EditorManager methods ================================ - - public void closeFile(@NotNull final VirtualFile file) { - closeFile(file, true, false); - } - - public void closeFile(@NotNull final VirtualFile file, final boolean moveFocus, final boolean closeAllCopies) { - assertDispatchThread(); - - final LocalFileSystem.WatchRequest request = file.getUserData(WATCH_REQUEST_KEY); - if (request != null) { - LocalFileSystem.getInstance().removeWatchedRoot(request); - } - - CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { - public void run() { - closeFileImpl(file, moveFocus, closeAllCopies); - } - }, "", null); - } - - - - private void closeFileImpl(@NotNull final VirtualFile file, final boolean moveFocus, boolean closeAllCopies) { - assertDispatchThread(); - runChange(new FileEditorManagerChange() { - public void run(EditorsSplitters splitters) { - splitters.closeFile(file, moveFocus); - } - }, closeAllCopies ? null : getActiveSplitters(true).getResult()); - } - - //-------------------------------------- Open File ---------------------------------------- - - @NotNull - public Pair openFileWithProviders(@NotNull final VirtualFile file, - final boolean focusEditor, - boolean searchForSplitter) { - if (!file.isValid()) { - throw new IllegalArgumentException("file is not valid: " + file); - } - assertDispatchThread(); - - EditorWindow wndToOpenIn = null; - if (searchForSplitter) { - Set all = getAllSplitters(); - EditorsSplitters active = getActiveSplitters(true).getResult(); - if (active.getCurrentWindow() != null && active.getCurrentWindow().isFileOpen(file)) { - wndToOpenIn = active.getCurrentWindow(); - } else { - for (EditorsSplitters splitters : all) { - final EditorWindow window = splitters.getCurrentWindow(); - if (window == null) continue; - - if (window.isFileOpen(file)) { - wndToOpenIn = window; - break; - } - } - } - } - else { - wndToOpenIn = getSplitters().getCurrentWindow(); - } - - EditorsSplitters splitters = getSplitters(); - - if (wndToOpenIn == null) { - wndToOpenIn = splitters.getOrCreateCurrentWindow(file); - } - - openAssociatedFile(file, wndToOpenIn, splitters); - return openFileImpl2(wndToOpenIn, file, focusEditor); - } - - private void openAssociatedFile(VirtualFile file, EditorWindow wndToOpenIn, EditorsSplitters splitters) { - EditorWindow[] windows = splitters.getWindows(); - - if (file != null && windows.length == 2) { - for (FileEditorAssociateFinder finder : Extensions.getExtensions(FileEditorAssociateFinder.EP_NAME)) { - VirtualFile associatedFile = finder.getAssociatedFileToOpen(myProject, file); - - if (associatedFile != null) { - EditorWindow currentWindow = splitters.getCurrentWindow(); - int idx = windows[0] == wndToOpenIn ? 1 : 0; - openFileImpl2(windows[idx], associatedFile, false); - - if (currentWindow != null) { - splitters.setCurrentWindow(currentWindow, false); - } - - break; - } - } - } - } - - @NotNull - @Override - public Pair openFileWithProviders(@NotNull VirtualFile file, - boolean focusEditor, - @NotNull EditorWindow window) { - if (!file.isValid()) { - throw new IllegalArgumentException("file is not valid: " + file); - } - assertDispatchThread(); - - return openFileImpl2(window, file, focusEditor); - } - - @NotNull - public Pair openFileImpl2(@NotNull final EditorWindow window, - @NotNull final VirtualFile file, - final boolean focusEditor) { - final Ref> result = new Ref>(); - CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { - public void run() { - result.set(openFileImpl3(window, file, focusEditor, null, true)); - } - }, "", null); - return result.get(); - } - - /** - * @param file to be opened. Unlike openFile method, file can be - * invalid. For example, all file were invalidate and they are being - * removed one by one. If we have removed one invalid file, then another - * invalid file become selected. That's why we do not require that - * passed file is valid. - * @param entry map between FileEditorProvider and FileEditorState. If this parameter - * @param current - */ - @NotNull - Pair openFileImpl3(@NotNull final EditorWindow window, - @NotNull final VirtualFile file, - final boolean focusEditor, - @Nullable final HistoryEntry entry, - boolean current) { - return openFileImpl4(window, file, focusEditor, entry, current, -1); - } - - @NotNull - Pair openFileImpl4(@NotNull final EditorWindow window, - @NotNull final VirtualFile file, - final boolean focusEditor, - @Nullable final HistoryEntry entry, - boolean current, - int index) { - // Open file - FileEditor[] editors; - FileEditorProvider[] providers; - final EditorWithProviderComposite newSelectedComposite; - boolean newEditorCreated = false; - - final boolean open = window.isFileOpen(file); - if (open) { - // File is already opened. In this case we have to just select existing EditorComposite - newSelectedComposite = window.findFileComposite(file); - LOG.assertTrue(newSelectedComposite != null); - - editors = newSelectedComposite.getEditors(); - providers = newSelectedComposite.getProviders(); - } - else { - // File is not opened yet. In this case we have to create editors - // and select the created EditorComposite. - final FileEditorProviderManager editorProviderManager = FileEditorProviderManager.getInstance(); - providers = editorProviderManager.getProviders(myProject, file); - if (DumbService.getInstance(myProject).isDumb()) { - final List dumbAware = ContainerUtil.findAll(providers, new Condition() { - public boolean value(FileEditorProvider fileEditorProvider) { - return DumbService.isDumbAware(fileEditorProvider); - } - }); - providers = dumbAware.toArray(new FileEditorProvider[dumbAware.size()]); - } - - if (providers.length == 0) { - return Pair.create(EMPTY_EDITOR_ARRAY, EMPTY_PROVIDER_ARRAY); - } - newEditorCreated = true; - - getProject().getMessageBus().syncPublisher(FileEditorManagerListener.Before.FILE_EDITOR_MANAGER).beforeFileOpened(this, file); - - editors = new FileEditor[providers.length]; - for (int i = 0; i < providers.length; i++) { - try { - final FileEditorProvider provider = providers[i]; - LOG.assertTrue(provider != null); - LOG.assertTrue(provider.accept(myProject, file)); - final FileEditor editor = provider.createEditor(myProject, file); - LOG.assertTrue(editor != null); - LOG.assertTrue(editor.isValid()); - editors[i] = editor; - // Register PropertyChangeListener into editor - editor.addPropertyChangeListener(myEditorPropertyChangeListener); - editor.putUserData(DUMB_AWARE, DumbService.isDumbAware(provider)); - - if (current && editor instanceof TextEditorImpl) { - ((TextEditorImpl)editor).initFolding(); - } - } - catch (Exception e) { - LOG.error(e); - } - catch (AssertionError e) { - LOG.error(e); - } - } - - // Now we have to create EditorComposite and insert it into the TabbedEditorComponent. - // After that we have to select opened editor. - newSelectedComposite = new EditorWithProviderComposite(file, editors, providers, this); - - if (index >= 0) { - newSelectedComposite.getFile().putUserData(EditorWindow.INITIAL_INDEX_KEY, index); - } - } - - window.setEditor(newSelectedComposite, focusEditor); - - final EditorHistoryManager editorHistoryManager = EditorHistoryManager.getInstance(myProject); - for (int i = 0; i < editors.length; i++) { - final FileEditor editor = editors[i]; - if (editor instanceof TextEditor) { - // hack!!! - // This code prevents "jumping" on next repaint. - ((EditorEx)((TextEditor)editor).getEditor()).stopOptimizedScrolling(); - } - - final FileEditorProvider provider = providers[i];//getProvider(editor); - - // Restore editor state - FileEditorState state = null; - if (entry != null) { - state = entry.getState(provider); - } - if (state == null && !open) { - // We have to try to get state from the history only in case - // if editor is not opened. Otherwise history entry might have a state - // out of sync with the current editor state. - state = editorHistoryManager.getState(file, provider); - } - if (state != null) { - editor.setState(state); - } - } - - // Restore selected editor - final FileEditorProvider selectedProvider = editorHistoryManager.getSelectedProvider(file); - if (selectedProvider != null) { - final FileEditor[] _editors = newSelectedComposite.getEditors(); - final FileEditorProvider[] _providers = newSelectedComposite.getProviders(); - for (int i = _editors.length - 1; i >= 0; i--) { - final FileEditorProvider provider = _providers[i];//getProvider(_editors[i]); - if (provider.equals(selectedProvider)) { - newSelectedComposite.setSelectedEditor(i); - break; - } - } - } - - // Notify editors about selection changes - window.getOwner().setCurrentWindow(window, focusEditor); - window.getOwner().afterFileOpen(file); - - newSelectedComposite.getSelectedEditor().selectNotify(); - - final IdeFocusManager focusManager = IdeFocusManager.getInstance(myProject); - if (newEditorCreated) { - if (window.isShowing()) { - window.setPaintBlocked(true); - } - notifyPublisher(new Runnable() { - @Override - public void run() { - window.setPaintBlocked(false); - if (isFileOpen(file)) { - getProject().getMessageBus().syncPublisher(FileEditorManagerListener.FILE_EDITOR_MANAGER) - .fileOpened(FileEditorManagerImpl.this, file); - } - } - }); - - //Add request to watch this editor's virtual file - final VirtualFile parentDir = file.getParent(); - if (parentDir != null) { - final LocalFileSystem.WatchRequest request = LocalFileSystem.getInstance().addRootToWatch(parentDir.getPath(), false); - file.putUserData(WATCH_REQUEST_KEY, request); - } - } - - //[jeka] this is a hack to support back-forward navigation - // previously here was incorrect call to fireSelectionChanged() with a side-effect - ((IdeDocumentHistoryImpl)IdeDocumentHistory.getInstance(myProject)).onSelectionChanged(); - - // Transfer focus into editor - if (!ApplicationManagerEx.getApplicationEx().isUnitTestMode()) { - if (focusEditor) { - //myFirstIsActive = myTabbedContainer1.equals(tabbedContainer); - window.setAsCurrentWindow(true); - ToolWindowManager.getInstance(myProject).activateEditorComponent(); - focusManager.toFront(window.getOwner()); - } - } - - // Update frame and tab title - updateFileName(file); - - // Make back/forward work - IdeDocumentHistory.getInstance(myProject).includeCurrentCommandAsNavigation(); - - return Pair.create(editors, providers); - } - - @Override - public ActionCallback notifyPublisher(final Runnable runnable) { - final IdeFocusManager focusManager = IdeFocusManager.getInstance(myProject); - final ActionCallback done = new ActionCallback(); - return myBusyObject.execute(new ActiveRunnable() { - @Override - public ActionCallback run() { - focusManager.doWhenFocusSettlesDown(new ExpirableRunnable.ForProject(myProject) { - @Override - public void run() { - runnable.run(); - done.setDone(); - } - }); - return done; - } - }); - } - - public void setSelectedEditor(VirtualFile file, String fileEditorProviderId) { - EditorWithProviderComposite composite = getCurrentEditorWithProviderComposite(file); - if (composite == null) { - final List composites = getEditorComposites(file); - - if (composites.isEmpty()) return; - composite = composites.get(0); - } - - final FileEditorProvider[] editorProviders = composite.getProviders(); - final FileEditorProvider selectedProvider = composite.getSelectedEditorWithProvider().getSecond(); - - for (int i = 0; i < editorProviders.length; i++) { - if (editorProviders[i].getEditorTypeId().equals(fileEditorProviderId) && !selectedProvider.equals(editorProviders[i])) { - composite.setSelectedEditor(i); - composite.getSelectedEditor().selectNotify(); - } - } - } - - - @Nullable - EditorWithProviderComposite newEditorComposite(final VirtualFile file) { - if (file == null) { - return null; - } - - final FileEditorProviderManager editorProviderManager = FileEditorProviderManager.getInstance(); - final FileEditorProvider[] providers = editorProviderManager.getProviders(myProject, file); - final FileEditor[] editors = new FileEditor[providers.length]; - for (int i = 0; i < providers.length; i++) { - final FileEditorProvider provider = providers[i]; - LOG.assertTrue(provider != null); - LOG.assertTrue(provider.accept(myProject, file)); - final FileEditor editor = provider.createEditor(myProject, file); - editors[i] = editor; - LOG.assertTrue(editor.isValid()); - editor.addPropertyChangeListener(myEditorPropertyChangeListener); - } - - final EditorWithProviderComposite newComposite = new EditorWithProviderComposite(file, editors, providers, this); - final EditorHistoryManager editorHistoryManager = EditorHistoryManager.getInstance(myProject); - for (int i = 0; i < editors.length; i++) { - final FileEditor editor = editors[i]; - if (editor instanceof TextEditor) { - // hack!!! - // This code prevents "jumping" on next repaint. - //((EditorEx)((TextEditor)editor).getEditor()).stopOptimizedScrolling(); - } - - final FileEditorProvider provider = providers[i]; - -// Restore myEditor state - FileEditorState state = editorHistoryManager.getState(file, provider); - if (state != null) { - editor.setState(state); - } - } - return newComposite; - } - - @NotNull - public List openEditor(@NotNull final OpenFileDescriptor descriptor, final boolean focusEditor) { - assertDispatchThread(); - if (descriptor.getFile() instanceof VirtualFileWindow) { - VirtualFileWindow delegate = (VirtualFileWindow)descriptor.getFile(); - int hostOffset = delegate.getDocumentWindow().injectedToHost(descriptor.getOffset()); - OpenFileDescriptor realDescriptor = new OpenFileDescriptor(descriptor.getProject(), delegate.getDelegate(), hostOffset); - realDescriptor.setUseCurrentWindow(descriptor.isUseCurrentWindow()); - return openEditor(realDescriptor, focusEditor); - } - - final List result = new ArrayList(); - CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { - public void run() { - VirtualFile file = descriptor.getFile(); - final FileEditor[] editors = openFile(file, focusEditor, !descriptor.isUseCurrentWindow()); - ContainerUtil.addAll(result, editors); - - boolean navigated = false; - for (final FileEditor editor : editors) { - if (editor instanceof NavigatableFileEditor && - getSelectedEditor(descriptor.getFile()) == editor) { // try to navigate opened editor - navigated = navigateAndSelectEditor((NavigatableFileEditor)editor, descriptor); - if (navigated) break; - } - } - - if (!navigated) { - for (final FileEditor editor : editors) { - if (editor instanceof NavigatableFileEditor && getSelectedEditor(descriptor.getFile()) != editor) { // try other editors - if (navigateAndSelectEditor((NavigatableFileEditor)editor, descriptor)) { - break; - } - } - } - } - } - }, "", null); - - return result; - } - - private boolean navigateAndSelectEditor(final NavigatableFileEditor editor, final OpenFileDescriptor descriptor) { - if (editor.canNavigateTo(descriptor)) { - setSelectedEditor(editor); - editor.navigateTo(descriptor); - return true; - } - - return false; - } - - private void setSelectedEditor(final FileEditor editor) { - final EditorWithProviderComposite composite = getEditorComposite(editor); - if (composite == null) return; - - final FileEditor[] editors = composite.getEditors(); - for (int i = 0; i < editors.length; i++) { - final FileEditor each = editors[i]; - if (editor == each) { - composite.setSelectedEditor(i); - composite.getSelectedEditor().selectNotify(); - break; - } - } - } - - @NotNull - public Project getProject() { - return myProject; - } - - @Nullable - public Editor openTextEditor(final OpenFileDescriptor descriptor, final boolean focusEditor) { - final Collection fileEditors = openEditor(descriptor, focusEditor); - for (FileEditor fileEditor : fileEditors) { - if (fileEditor instanceof TextEditor) { - setSelectedEditor(descriptor.getFile(), TextEditorProvider.getInstance().getEditorTypeId()); - Editor editor = ((TextEditor)fileEditor).getEditor(); - return getOpenedEditor(editor, focusEditor); - } - } - - return null; - } - - protected Editor getOpenedEditor(final Editor editor, final boolean focusEditor) { - return editor; - } - - public Editor getSelectedTextEditor() { - assertReadAccess(); - - final EditorWindow currentWindow = getSplitters().getCurrentWindow(); - if (currentWindow != null) { - final EditorWithProviderComposite selectedEditor = currentWindow.getSelectedEditor(); - if (selectedEditor != null && selectedEditor.getSelectedEditor() instanceof TextEditor) { - return ((TextEditor)selectedEditor.getSelectedEditor()).getEditor(); - } - } - - return null; - } - - - public boolean isFileOpen(@NotNull final VirtualFile file) { - return !getEditorComposites(file).isEmpty(); - } - - @NotNull - public VirtualFile[] getOpenFiles() { - HashSet openFiles = new HashSet(); - for (EditorsSplitters each : getAllSplitters()) { - openFiles.addAll(Arrays.asList(each.getOpenFiles())); - } - - return VfsUtilCore.toVirtualFileArray(openFiles); - } - - @NotNull - public VirtualFile[] getSelectedFiles() { - HashSet selectedFiles = new HashSet(); - for (EditorsSplitters each : getAllSplitters()) { - selectedFiles.addAll(Arrays.asList(each.getSelectedFiles())); - } - - return VfsUtilCore.toVirtualFileArray(selectedFiles); - } - - @NotNull - public FileEditor[] getSelectedEditors() { - HashSet selectedEditors = new HashSet(); - for (EditorsSplitters each : getAllSplitters()) { - selectedEditors.addAll(Arrays.asList(each.getSelectedEditors())); - } - - return selectedEditors.toArray(new FileEditor[selectedEditors.size()]); - } - - public EditorsSplitters getSplitters() { - EditorsSplitters active = getActiveSplitters(true).getResult(); - return active == null ? getMainSplitters() : active; - } - - @Nullable - public FileEditor getSelectedEditor(@NotNull final VirtualFile file) { - final Pair selectedEditorWithProvider = getSelectedEditorWithProvider(file); - return selectedEditorWithProvider == null ? null : selectedEditorWithProvider.getFirst(); - } - - - @Nullable - public Pair getSelectedEditorWithProvider(@NotNull VirtualFile file) { - if (file instanceof VirtualFileWindow) file = ((VirtualFileWindow)file).getDelegate(); - final EditorWithProviderComposite composite = getCurrentEditorWithProviderComposite(file); - if (composite != null) { - return composite.getSelectedEditorWithProvider(); - } - - final List composites = getEditorComposites(file); - return composites.isEmpty() ? null : composites.get(0).getSelectedEditorWithProvider(); - } - - @NotNull - public Pair getEditorsWithProviders(@NotNull final VirtualFile file) { - assertReadAccess(); - - final EditorWithProviderComposite composite = getCurrentEditorWithProviderComposite(file); - if (composite != null) { - return Pair.create(composite.getEditors(), composite.getProviders()); - } - - final List composites = getEditorComposites(file); - if (!composites.isEmpty()) { - return Pair.create(composites.get(0).getEditors(), composites.get(0).getProviders()); - } - else { - return Pair.create(EMPTY_EDITOR_ARRAY, EMPTY_PROVIDER_ARRAY); - } - } - - @NotNull - public FileEditor[] getEditors(@NotNull VirtualFile file) { - assertReadAccess(); - if (file instanceof VirtualFileWindow) file = ((VirtualFileWindow)file).getDelegate(); - - final EditorWithProviderComposite composite = getCurrentEditorWithProviderComposite(file); - if (composite != null) { - return composite.getEditors(); - } - - final List composites = getEditorComposites(file); - if (!composites.isEmpty()) { - return composites.get(0).getEditors(); - } - else { - return EMPTY_EDITOR_ARRAY; - } - } - - @NotNull - @Override - public FileEditor[] getAllEditors(@NotNull VirtualFile file) { - List editorComposites = getEditorComposites(file); - List editors = new ArrayList(); - for (EditorWithProviderComposite composite : editorComposites) { - ContainerUtil.addAll(editors, composite.getEditors()); - } - return editors.toArray(new FileEditor[editors.size()]); - } - - @Nullable - private EditorWithProviderComposite getCurrentEditorWithProviderComposite(@NotNull final VirtualFile virtualFile) { - final EditorWindow editorWindow = getSplitters().getCurrentWindow(); - if (editorWindow != null) { - return editorWindow.findFileComposite(virtualFile); - } - return null; - } - - @NotNull - public List getEditorComposites(final VirtualFile file) { - ArrayList result = new ArrayList(); - Set all = getAllSplitters(); - for (EditorsSplitters each : all) { - result.addAll(each.findEditorComposites(file)); - } - return result; - } - - @NotNull - public FileEditor[] getAllEditors() { - assertReadAccess(); - final ArrayList result = new ArrayList(); - final Set allSplitters = getAllSplitters(); - for (EditorsSplitters splitter : allSplitters) { - final EditorWithProviderComposite[] editorsComposites = splitter.getEditorsComposites(); - for (EditorWithProviderComposite editorsComposite : editorsComposites) { - final FileEditor[] editors = editorsComposite.getEditors(); - ContainerUtil.addAll(result, editors); - } - } - return result.toArray(new FileEditor[result.size()]); - } - - public void showEditorAnnotation(@NotNull FileEditor editor, @NotNull JComponent annotationComponent) { - addTopComponent(editor, annotationComponent); - } - - public void removeEditorAnnotation(@NotNull FileEditor editor, @NotNull JComponent annotationComponent) { - removeTopComponent(editor, annotationComponent); - } - - public void addTopComponent(@NotNull final FileEditor editor, @NotNull final JComponent component) { - final EditorComposite composite = getEditorComposite(editor); - if (composite != null) { - composite.addTopComponent(editor, component); - } - } - - public void removeTopComponent(@NotNull final FileEditor editor, @NotNull final JComponent component) { - final EditorComposite composite = getEditorComposite(editor); - if (composite != null) { - composite.removeTopComponent(editor, component); - } - } - - public void addBottomComponent(@NotNull final FileEditor editor, @NotNull final JComponent component) { - final EditorComposite composite = getEditorComposite(editor); - if (composite != null) { - composite.addBottomComponent(editor, component); - } - } - - public void removeBottomComponent(@NotNull final FileEditor editor, @NotNull final JComponent component) { - final EditorComposite composite = getEditorComposite(editor); - if (composite != null) { - composite.removeBottomComponent(editor, component); - } - } - - private final MessageListenerList myListenerList; - - public void addFileEditorManagerListener(@NotNull final FileEditorManagerListener listener) { - myListenerList.add(listener); - } - - public void addFileEditorManagerListener(@NotNull final FileEditorManagerListener listener, final Disposable parentDisposable) { - myListenerList.add(listener, parentDisposable); - } - - public void removeFileEditorManagerListener(@NotNull final FileEditorManagerListener listener) { - myListenerList.remove(listener); - } - -// ProjectComponent methods - - public void projectOpened() { - //myFocusWatcher.install(myWindows.getComponent ()); - getMainSplitters().startListeningFocus(); - - MessageBusConnection connection = myProject.getMessageBus().connect(myProject); - - final FileStatusManager fileStatusManager = FileStatusManager.getInstance(myProject); - if (fileStatusManager != null) { - /** - * Updates tabs colors - */ - final MyFileStatusListener myFileStatusListener = new MyFileStatusListener(); - fileStatusManager.addFileStatusListener(myFileStatusListener, myProject); - } - connection.subscribe(FileTypeManager.TOPIC, new MyFileTypeListener()); - connection.subscribe(ProjectTopics.PROJECT_ROOTS, new MyRootsListener()); - - /** - * Updates tabs names - */ - final MyVirtualFileListener myVirtualFileListener = new MyVirtualFileListener(); - VirtualFileManager.getInstance().addVirtualFileListener(myVirtualFileListener, myProject); - /** - * Extends/cuts number of opened tabs. Also updates location of tabs. - */ - final MyUISettingsListener myUISettingsListener = new MyUISettingsListener(); - UISettings.getInstance().addUISettingsListener(myUISettingsListener, myProject); - - StartupManager.getInstance(myProject).registerPostStartupActivity(new DumbAwareRunnable() { - public void run() { - - setTabsMode(UISettings.getInstance().EDITOR_TAB_PLACEMENT != UISettings.TABS_NONE); - - ToolWindowManager.getInstance(myProject).invokeLater(new Runnable() { - public void run() { - CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { - public void run() { - - LaterInvocator.invokeLater(new Runnable() { - public void run() { - long currentTime = System.nanoTime(); - Long startTime = myProject.getUserData(ProjectImpl.CREATION_TIME); - if (startTime != null) { - LOG.info("Project opening took " + (currentTime - startTime.longValue()) / 1000000 + " ms"); - PluginManager.dumpPluginClassStatistics(); - } - } - }); -// group 1 - } - }, "", null); - } - }); - } - }); - } - - public void projectClosed() { - //myFocusWatcher.deinstall(myWindows.getComponent ()); - getMainSplitters().dispose(); - -// Dispose created editors. We do not use use closeEditor method because -// it fires event and changes history. - closeAllFiles(); - } - -// BaseCompomemnt methods - - @NotNull - public String getComponentName() { - return "FileEditorManager"; - } - - public void initComponent() { - - } - - public void disposeComponent() { /* really do nothing */ } - -//JDOMExternalizable methods - - public void writeExternal(final Element element) { - getMainSplitters().writeExternal(element); - } - - public void readExternal(final Element element) { - getMainSplitters().readExternal(element); - } - - @Nullable - private EditorWithProviderComposite getEditorComposite(@NotNull final FileEditor editor) { - for (EditorsSplitters splitters : getAllSplitters()) { - final EditorWithProviderComposite[] editorsComposites = splitters.getEditorsComposites(); - for (int i = editorsComposites.length - 1; i >= 0; i--) { - final EditorWithProviderComposite composite = editorsComposites[i]; - final FileEditor[] editors = composite.getEditors(); - for (int j = editors.length - 1; j >= 0; j--) { - final FileEditor _editor = editors[j]; - LOG.assertTrue(_editor != null); - if (editor.equals(_editor)) { - return composite; - } - } - } - } - return null; - } - -//======================= Misc ===================== - - private static void assertDispatchThread() { - ApplicationManager.getApplication().assertIsDispatchThread(); - } - - private static void assertReadAccess() { - ApplicationManager.getApplication().assertReadAccessAllowed(); - } - - public void fireSelectionChanged(final EditorComposite newSelectedComposite) { - final Trinity oldData = extract(myLastSelectedComposite.get()); - final Trinity newData = extract(newSelectedComposite); - myLastSelectedComposite = new WeakReference(newSelectedComposite); - final boolean filesEqual = oldData.first == null ? newData.first == null : oldData.first.equals(newData.first); - final boolean editorsEqual = oldData.second == null ? newData.second == null : oldData.second.equals(newData.second); - if (!filesEqual || !editorsEqual) { - if (oldData.first != null && newData.first != null) { - for (FileEditorAssociateFinder finder : Extensions.getExtensions(FileEditorAssociateFinder.EP_NAME)) { - VirtualFile associatedFile = finder.getAssociatedFileToOpen(myProject, oldData.first); - - if (associatedFile == newData.first) { - return; - } - } - } - - final FileEditorManagerEvent event = - new FileEditorManagerEvent(this, oldData.first, oldData.second, oldData.third, newData.first, newData.second, newData.third); - final FileEditorManagerListener publisher = getProject().getMessageBus().syncPublisher(FileEditorManagerListener.FILE_EDITOR_MANAGER); - - if (newData.first != null) { - final JComponent component = newData.second.getComponent(); - final EditorWindowHolder holder = UIUtil.getParentOfType(EditorWindowHolder.class, component); - if (holder != null) { - addSelectionRecord(newData.first, holder.getEditorWindow()); - } - } - notifyPublisher(new Runnable() { - @Override - public void run() { - publisher.selectionChanged(event); - } - }); - } - } - - @NotNull - private static Trinity extract(@Nullable EditorComposite composite) { - final VirtualFile file; - final FileEditor editor; - final FileEditorProvider provider; - if (composite == null || composite.isDisposed()) { - file = null; - editor = null; - provider = null; - } - else { - file = composite.getFile(); - final Pair pair = composite.getSelectedEditorWithProvider(); - editor = pair.first; - provider = pair.second; - } - return new Trinity(file, editor, provider); - } - - public boolean isChanged(@NotNull final EditorComposite editor) { - final FileStatusManager fileStatusManager = FileStatusManager.getInstance(myProject); - if (fileStatusManager != null) { - VirtualFile file = editor.getFile(); - FileStatus status = fileStatusManager.getStatus(file); - if (status == FileStatus.UNKNOWN && !file.isWritable()) { - return false; - } - if (!status.equals(FileStatus.NOT_CHANGED)) { - return true; - } - } - return false; - } - - public void disposeComposite(@NotNull EditorWithProviderComposite editor) { - if (getAllEditors().length == 0) { - setCurrentWindow(null); - } - - if (editor.equals(getLastSelected())) { - editor.getSelectedEditor().deselectNotify(); - getSplitters().setCurrentWindow(null, false); - } - - final FileEditor[] editors = editor.getEditors(); - final FileEditorProvider[] providers = editor.getProviders(); - - final FileEditor selectedEditor = editor.getSelectedEditor(); - for (int i = editors.length - 1; i >= 0; i--) { - final FileEditor editor1 = editors[i]; - final FileEditorProvider provider = providers[i]; - if (!editor.equals(selectedEditor)) { // we already notified the myEditor (when fire event) - if (selectedEditor.equals(editor1)) { - editor1.deselectNotify(); - } - } - editor1.removePropertyChangeListener(myEditorPropertyChangeListener); - provider.disposeEditor(editor1); - } - - Disposer.dispose(editor); - } - - @Nullable - EditorComposite getLastSelected() { - final EditorWindow currentWindow = getActiveSplitters(true).getResult().getCurrentWindow(); - if (currentWindow != null) { - return currentWindow.getSelectedEditor(); - } - return null; - } - - public void runChange(FileEditorManagerChange change, EditorsSplitters splitters) { - Set target = new HashSet(); - if (splitters == null) { - target.addAll(getAllSplitters()); - } else { - target.add(splitters); - } - - for (EditorsSplitters each : target) { - each.myInsideChange++; - try { - change.run(each); - } - finally { - each.myInsideChange--; - } - } - } - - //================== Listeners ===================== - - /** - * Closes deleted files. Closes file which are in the deleted directories. - */ - private final class MyVirtualFileListener extends VirtualFileAdapter { - public void beforeFileDeletion(VirtualFileEvent e) { - assertDispatchThread(); - - boolean moveFocus = moveFocusOnDelete(); - - final VirtualFile file = e.getFile(); - final VirtualFile[] openFiles = getOpenFiles(); - for (int i = openFiles.length - 1; i >= 0; i--) { - if (VfsUtilCore.isAncestor(file, openFiles[i], false)) { - closeFile(openFiles[i], moveFocus, true); - } - } - } - - public void propertyChanged(VirtualFilePropertyEvent e) { - if (VirtualFile.PROP_NAME.equals(e.getPropertyName())) { - assertDispatchThread(); - final VirtualFile file = e.getFile(); - if (isFileOpen(file)) { - updateFileName(file); - updateFileIcon(file); // file type can change after renaming - updateFileBackgroundColor(file); - } - } - else if (VirtualFile.PROP_WRITABLE.equals(e.getPropertyName()) || VirtualFile.PROP_ENCODING.equals(e.getPropertyName())) { - // TODO: message bus? - updateIconAndStatusBar(e); - } - } - - private void updateIconAndStatusBar(final VirtualFilePropertyEvent e) { - assertDispatchThread(); - final VirtualFile file = e.getFile(); - if (isFileOpen(file)) { - updateFileIcon(file); - if (file.equals(getSelectedFiles()[0])) { // update "write" status - final StatusBarEx statusBar = (StatusBarEx)WindowManager.getInstance().getStatusBar(myProject); - assert statusBar != null; - statusBar.updateWidgets(); - } - } - } - - public void fileMoved(VirtualFileMoveEvent e) { - final VirtualFile file = e.getFile(); - final VirtualFile[] openFiles = getOpenFiles(); - for (final VirtualFile openFile : openFiles) { - if (VfsUtilCore.isAncestor(file, openFile, false)) { - updateFileName(openFile); - updateFileBackgroundColor(openFile); - } - } - } - } - - private static boolean moveFocusOnDelete() { - final Window window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow(); - if (window != null) { - final Component component = FocusTrackback.getFocusFor(window); - if (component != null) { - return component instanceof EditorComponentImpl; - } - return window instanceof IdeFrameImpl; - } - return true; - } - - public boolean isInsideChange() { - return getSplitters().isInsideChange(); - } - - private final class MyEditorPropertyChangeListener implements PropertyChangeListener { - public void propertyChange(final PropertyChangeEvent e) { - assertDispatchThread(); - - final String propertyName = e.getPropertyName(); - if (FileEditor.PROP_MODIFIED.equals(propertyName)) { - final FileEditor editor = (FileEditor)e.getSource(); - final EditorComposite composite = getEditorComposite(editor); - if (composite != null) { - updateFileIcon(composite.getFile()); - } - } - else if (FileEditor.PROP_VALID.equals(propertyName)) { - final boolean valid = ((Boolean)e.getNewValue()).booleanValue(); - if (!valid) { - final FileEditor editor = (FileEditor)e.getSource(); - LOG.assertTrue(editor != null); - final EditorComposite composite = getEditorComposite(editor); - if (composite != null) { - closeFile(composite.getFile()); - } - } - } - - } - } - - - /** - * Gets events from VCS and updates color of myEditor tabs - */ - private final class MyFileStatusListener implements FileStatusListener { - public void fileStatusesChanged() { // update color of all open files - assertDispatchThread(); - LOG.debug("FileEditorManagerImpl.MyFileStatusListener.fileStatusesChanged()"); - final VirtualFile[] openFiles = getOpenFiles(); - for (int i = openFiles.length - 1; i >= 0; i--) { - final VirtualFile file = openFiles[i]; - LOG.assertTrue(file != null); - ApplicationManager.getApplication().invokeLater(new Runnable() { - public void run() { - if (LOG.isDebugEnabled()) { - LOG.debug("updating file status in tab for " + file.getPath()); - } - updateFileStatus(file); - } - }, ModalityState.NON_MODAL, myProject.getDisposed()); - } - } - - public void fileStatusChanged(@NotNull final VirtualFile file) { // update color of the file (if necessary) - assertDispatchThread(); - if (isFileOpen(file)) { - updateFileStatus(file); - } - } - - private void updateFileStatus(final VirtualFile file) { - updateFileColor(file); - updateFileIcon(file); - } - } - - /** - * Gets events from FileTypeManager and updates icons on tabs - */ - private final class MyFileTypeListener implements FileTypeListener { - public void beforeFileTypesChanged(FileTypeEvent event) { - } - - public void fileTypesChanged(final FileTypeEvent event) { - assertDispatchThread(); - final VirtualFile[] openFiles = getOpenFiles(); - for (int i = openFiles.length - 1; i >= 0; i--) { - final VirtualFile file = openFiles[i]; - LOG.assertTrue(file != null); - updateFileIcon(file); - } - } - } - - private class MyRootsListener extends ModuleRootAdapter { - public void rootsChanged(ModuleRootEvent event) { - EditorFileSwapper[] swappers = Extensions.getExtensions(EditorFileSwapper.EP_NAME); - - for (EditorWindow eachWindow : getWindows()) { - EditorWithProviderComposite selected = eachWindow.getSelectedEditor(); - EditorWithProviderComposite[] editors = eachWindow.getEditors(); - for (int i = 0; i < editors.length; i++) { - EditorWithProviderComposite editor = editors[i]; - VirtualFile file = editor.getFile(); - if (!file.isValid()) continue; - - Pair newFilePair = null; - - for (EditorFileSwapper each : swappers) { - newFilePair = each.getFileToSwapTo(myProject, editor); - if (newFilePair != null) break; - } - - if (newFilePair == null) continue; - - VirtualFile newFile = newFilePair.first; - if (newFile == null) continue; - - // already open - if (eachWindow.findFileIndex(newFile) != -1) continue; - - try { - newFile.putUserData(EditorWindow.INITIAL_INDEX_KEY, i); - Pair pair = openFileImpl2(eachWindow, newFile, editor == selected); - - if (newFilePair.second != null) { - TextEditorImpl openedEditor = EditorFileSwapper.findSinglePsiAwareEditor(pair.first); - if (openedEditor != null) { - openedEditor.getEditor().getCaretModel().moveToOffset(newFilePair.second); - openedEditor.getEditor().getScrollingModel().scrollToCaret(ScrollType.CENTER); - } - } - } - finally { - newFile.putUserData(EditorWindow.INITIAL_INDEX_KEY, null); - } - closeFile(file, eachWindow); - } - } - } - } - - /** - * Gets notifications from UISetting component to track changes of RECENT_FILES_LIMIT - * and EDITOR_TAB_LIMIT, etc values. - */ - private final class MyUISettingsListener implements UISettingsListener { - public void uiSettingsChanged(final UISettings source) { - assertDispatchThread(); - setTabsMode(source.EDITOR_TAB_PLACEMENT != UISettings.TABS_NONE); - - for (EditorsSplitters each : getAllSplitters()) { - each.setTabsPlacement(source.EDITOR_TAB_PLACEMENT); - each.trimToSize(source.EDITOR_TAB_LIMIT); - - // Tab layout policy - if (source.SCROLL_TAB_LAYOUT_IN_EDITOR) { - each.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); - } - else { - each.setTabLayoutPolicy(JTabbedPane.WRAP_TAB_LAYOUT); - } - } - - // "Mark modified files with asterisk" - final VirtualFile[] openFiles = getOpenFiles(); - for (int i = openFiles.length - 1; i >= 0; i--) { - final VirtualFile file = openFiles[i]; - updateFileIcon(file); - updateFileName(file); - updateFileBackgroundColor(file); - } - } - } - - public void closeAllFiles() { - final VirtualFile[] openFiles = getSplitters().getOpenFiles(); - for (VirtualFile openFile : openFiles) { - closeFile(openFile); - } - } - - @NotNull - public VirtualFile[] getSiblings(VirtualFile file) { - return getOpenFiles(); - } - - protected void queueUpdateFile(final VirtualFile file) { - myQueue.queue(new Update(file) { - public void run() { - if (isFileOpen(file)) { - updateFileIcon(file); - updateFileColor(file); - updateFileBackgroundColor(file); - } - - } - }); - } - - public EditorsSplitters getSplittersFor(Component c) { - EditorsSplitters splitters = null; - DockContainer dockContainer = myDockManager.getContainerFor(c); - if (dockContainer instanceof DockableEditorTabbedContainer) { - splitters = ((DockableEditorTabbedContainer)dockContainer).getSplitters(); - } - - if (splitters == null) { - splitters = getMainSplitters(); - } - - return splitters; - } - - public List> getSelectionHistory() { - List> copy = new ArrayList>(); - for (Pair pair : mySelectionHistory) { - if (pair.second.getFiles().length == 0) { - final EditorWindow[] windows = pair.second.getOwner().getWindows(); - if (windows.length > 0 && windows[0] != null && windows[0].getFiles().length > 0) { - final Pair p = Pair.create(pair.first, windows[0]); - if (!copy.contains(p)) { - copy.add(p); - } - } - } else { - if (!copy.contains(pair)) { - copy.add(pair); - } - } - } - mySelectionHistory.clear(); - mySelectionHistory.addAll(copy); - return mySelectionHistory; - } - - public void addSelectionRecord(VirtualFile file, EditorWindow window) { - final Pair record = Pair.create(file, window); - mySelectionHistory.remove(record); - mySelectionHistory.add(0, record); - } - - public void removeSelectionRecord(VirtualFile file, EditorWindow window) { - mySelectionHistory.remove(Pair.create(file, window)); - } - - @Override - public ActionCallback getReady(@NotNull Object requestor) { - return myBusyObject.getReady(requestor); - } -} +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.fileEditor.impl; + +import com.intellij.ProjectTopics; +import com.intellij.ide.IdeBundle; +import com.intellij.ide.plugins.PluginManager; +import com.intellij.ide.ui.UISettings; +import com.intellij.ide.ui.UISettingsListener; +import com.intellij.injected.editor.VirtualFileWindow; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.application.impl.LaterInvocator; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.impl.EditorComponentImpl; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.fileEditor.*; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager; +import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; +import com.intellij.openapi.fileEditor.impl.text.TextEditorImpl; +import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider; +import com.intellij.openapi.fileTypes.FileTypeEvent; +import com.intellij.openapi.fileTypes.FileTypeListener; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.project.DumbAwareRunnable; +import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.impl.ProjectImpl; +import com.intellij.openapi.roots.ModuleRootAdapter; +import com.intellij.openapi.roots.ModuleRootEvent; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.*; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.registry.Registry; +import com.intellij.openapi.vcs.FileStatus; +import com.intellij.openapi.vcs.FileStatusListener; +import com.intellij.openapi.vcs.FileStatusManager; +import com.intellij.openapi.vfs.*; +import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.openapi.wm.ex.StatusBarEx; +import com.intellij.openapi.wm.impl.IdeFrameImpl; +import com.intellij.ui.FocusTrackback; +import com.intellij.ui.docking.DockContainer; +import com.intellij.ui.docking.DockManager; +import com.intellij.ui.tabs.impl.JBTabsImpl; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.messages.MessageBusConnection; +import com.intellij.util.messages.impl.MessageListenerList; +import com.intellij.util.ui.SameColor; +import com.intellij.util.ui.UIUtil; +import com.intellij.util.ui.update.MergingUpdateQueue; +import com.intellij.util.ui.update.Update; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.border.Border; +import java.awt.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.lang.ref.WeakReference; +import java.util.*; +import java.util.List; + +/** + * @author Anton Katilin + * @author Eugene Belyaev + * @author Vladimir Kondratyev + */ +public class FileEditorManagerImpl extends FileEditorManagerEx implements ProjectComponent, JDOMExternalizable { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl"); + private static final Key WATCH_REQUEST_KEY = Key.create("WATCH_REQUEST_KEY"); + private static final Key DUMB_AWARE = Key.create("DUMB_AWARE"); + + private static final FileEditor[] EMPTY_EDITOR_ARRAY = {}; + private static final FileEditorProvider[] EMPTY_PROVIDER_ARRAY = {}; + public static final Key CLOSING_TO_REOPEN = Key.create("CLOSING_TO_REOPEN"); + + private volatile JPanel myPanels; + private EditorsSplitters mySplitters; + private final Project myProject; + private final List> mySelectionHistory = new ArrayList>(); + private WeakReference myLastSelectedComposite = new WeakReference(null); + + + private final MergingUpdateQueue myQueue = new MergingUpdateQueue("FileEditorManagerUpdateQueue", 50, true, null); + + private final BusyObject.Impl.Simple myBusyObject = new BusyObject.Impl.Simple(); + + /** + * Removes invalid myEditor and updates "modified" status. + */ + private final MyEditorPropertyChangeListener myEditorPropertyChangeListener = new MyEditorPropertyChangeListener(); + private final DockManager myDockManager; + private DockableEditorContainerFactory myContentFactory; + + public FileEditorManagerImpl(final Project project, DockManager dockManager) { +/* ApplicationManager.getApplication().assertIsDispatchThread(); */ + myProject = project; + myDockManager = dockManager; + myListenerList = + new MessageListenerList(myProject.getMessageBus(), FileEditorManagerListener.FILE_EDITOR_MANAGER); + + if (Extensions.getExtensions(FileEditorAssociateFinder.EP_NAME).length > 0) { + myListenerList.add(new FileEditorManagerAdapter() { + @Override + public void selectionChanged(FileEditorManagerEvent event) { + EditorsSplitters splitters = getSplitters(); + openAssociatedFile(event.getNewFile(), splitters.getCurrentWindow(), splitters); + } + }); + } + + myQueue.setTrackUiActivity(true); + } + + void initDockableContentFactory() { + if (myContentFactory != null) return; + + myContentFactory = new DockableEditorContainerFactory(myProject, this, myDockManager); + myDockManager.register(DockableEditorContainerFactory.TYPE, myContentFactory); + Disposer.register(myProject, myContentFactory); + } + + public static boolean isDumbAware(FileEditor editor) { + return Boolean.TRUE.equals(editor.getUserData(DUMB_AWARE)); + } + + //------------------------------------------------------------------------------- + + public JComponent getComponent() { + initUI(); + return myPanels; + } + + public EditorsSplitters getMainSplitters() { + initUI(); + + return mySplitters; + } + + public Set getAllSplitters() { + HashSet all = new HashSet(); + all.add(getMainSplitters()); + Set dockContainers = myDockManager.getContainers(); + for (DockContainer each : dockContainers) { + if (each instanceof DockableEditorTabbedContainer) { + all.add(((DockableEditorTabbedContainer)each).getSplitters()); + } + } + + return Collections.unmodifiableSet(all); + } + + private AsyncResult getActiveSplitters(boolean syncUsage) { + final boolean async = Registry.is("ide.windowSystem.asyncSplitters") && !syncUsage; + + final AsyncResult result = new AsyncResult(); + final IdeFocusManager fm = IdeFocusManager.getInstance(myProject); + Runnable run = new Runnable() { + @Override + public void run() { + if (myProject.isDisposed()) { + result.setRejected(); + return; + } + + Component focusOwner = fm.getFocusOwner(); + if (focusOwner == null && !async) { + focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); + } + + if (focusOwner == null && !async) { + focusOwner = fm.getLastFocusedFor(fm.getLastFocusedFrame()); + } + + DockContainer container = myDockManager.getContainerFor(focusOwner); + if (container == null && !async) { + focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow(); + container = myDockManager.getContainerFor(focusOwner); + } + + if (container instanceof DockableEditorTabbedContainer) { + result.setDone(((DockableEditorTabbedContainer)container).getSplitters()); + } + else { + result.setDone(getMainSplitters()); + } + } + }; + + if (async) { + fm.doWhenFocusSettlesDown(run); + } + else { + run.run(); + } + + return result; + } + + private final Object myInitLock = new Object(); + + private void initUI() { + if (myPanels == null) { + synchronized (myInitLock) { + if (myPanels == null) { + myPanels = new JPanel(new BorderLayout()) { + @Override + public Color getBackground() { + boolean navBar = UISettings.getInstance().SHOW_NAVIGATION_BAR; + if (navBar) { + return UIUtil.getSlightlyDarkerColor(UIUtil.isUnderAquaLookAndFeel() ? new SameColor(200) : UIUtil.getPanelBackground()); + } else { + return UIUtil.isUnderAquaLookAndFeel() ? new SameColor(189) : UIUtil.getPanelBackground(); + } + } + }; + myPanels.setBorder(new MyBorder()); + mySplitters = new EditorsSplitters(this, myDockManager, true); + myPanels.add(mySplitters, BorderLayout.CENTER); + } + } + } + } + + private static class MyBorder implements Border { + @Override + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + if (UIUtil.isUnderAquaLookAndFeel()) { + g.setColor(JBTabsImpl.MAC_AQUA_BG_COLOR); + final Insets insets = getBorderInsets(c); + if (insets.top > 0) { + g.fillRect(x, y, width, height + insets.top); + } + } + } + + @Override + public Insets getBorderInsets(Component c) { + return new Insets(0, 0, 0, 0); + } + + @Override + public boolean isBorderOpaque() { + return false; + } + } + + public JComponent getPreferredFocusedComponent() { + assertReadAccess(); + final EditorWindow window = getSplitters().getCurrentWindow(); + if (window != null) { + final EditorWithProviderComposite editor = window.getSelectedEditor(); + if (editor != null) { + return editor.getPreferredFocusedComponent(); + } + } + return null; + } + + //------------------------------------------------------- + + /** + * @return color of the file which corresponds to the + * file's status + */ + public Color getFileColor(@NotNull final VirtualFile file) { + final FileStatusManager fileStatusManager = FileStatusManager.getInstance(myProject); + Color statusColor = fileStatusManager != null ? fileStatusManager.getStatus(file).getColor() : Color.BLACK; + if (statusColor == null) statusColor = Color.BLACK; + return statusColor; + } + + public boolean isProblem(@NotNull final VirtualFile file) { + return false; + } + + public String getFileTooltipText(VirtualFile file) { + return FileUtil.getLocationRelativeToUserHome(file.getPresentableUrl()); + } + + public void updateFilePresentation(VirtualFile file) { + if (!isFileOpen(file)) return; + + updateFileColor(file); + updateFileIcon(file); + updateFileName(file); + updateFileBackgroundColor(file); + } + + /** + * Updates tab color for the specified file. The file + * should be opened in the myEditor, otherwise the method throws an assertion. + */ + private void updateFileColor(final VirtualFile file) { + Set all = getAllSplitters(); + for (EditorsSplitters each : all) { + each.updateFileColor(file); + } + } + + private void updateFileBackgroundColor(final VirtualFile file) { + Set all = getAllSplitters(); + for (EditorsSplitters each : all) { + each.updateFileBackgroundColor(file); + } + } + + /** + * Updates tab icon for the specified file. The file + * should be opened in the myEditor, otherwise the method throws an assertion. + */ + protected void updateFileIcon(final VirtualFile file) { + Set all = getAllSplitters(); + for (EditorsSplitters each : all) { + each.updateFileIcon(file); + } + } + + /** + * Updates tab title and tab tool tip for the specified file + */ + void updateFileName(@Nullable final VirtualFile file) { + // Queue here is to prevent title flickering when tab is being closed and two events arriving: with component==null and component==next focused tab + // only the last event makes sense to handle + myQueue.queue(new Update("UpdateFileName " + (file == null ? "" : file.getPath())) { + public boolean isExpired() { + return myProject.isDisposed() || !myProject.isOpen() || (file == null ? super.isExpired() : !file.isValid()); + } + + public void run() { + Set all = getAllSplitters(); + for (EditorsSplitters each : all) { + each.updateFileName(file); + } + } + }); + } + + //------------------------------------------------------- + + + public VirtualFile getFile(@NotNull final FileEditor editor) { + final EditorComposite editorComposite = getEditorComposite(editor); + if (editorComposite != null) { + return editorComposite.getFile(); + } + return null; + } + + public void unsplitWindow() { + final EditorWindow currentWindow = getActiveSplitters(true).getResult().getCurrentWindow(); + if (currentWindow != null) { + currentWindow.unsplit(true); + } + } + + public void unsplitAllWindow() { + final EditorWindow currentWindow = getActiveSplitters(true).getResult().getCurrentWindow(); + if (currentWindow != null) { + currentWindow.unsplitAll(); + } + } + + @Override + public int getWindowSplitCount() { + return getActiveSplitters(true).getResult().getSplitCount(); + } + + @Override + public boolean hasSplitOrUndockedWindows() { + Set splitters = getAllSplitters(); + if (splitters.size() > 1) return true; + return getWindowSplitCount() > 1; + } + + @NotNull + public EditorWindow[] getWindows() { + ArrayList windows = new ArrayList(); + Set all = getAllSplitters(); + for (EditorsSplitters each : all) { + EditorWindow[] eachList = each.getWindows(); + windows.addAll(Arrays.asList(eachList)); + } + + return windows.toArray(new EditorWindow[windows.size()]); + } + + public EditorWindow getNextWindow(@NotNull final EditorWindow window) { + final EditorWindow[] windows = getSplitters().getOrderedWindows(); + for (int i = 0; i != windows.length; ++i) { + if (windows[i].equals(window)) { + return windows[(i + 1) % windows.length]; + } + } + LOG.error("Not window found"); + return null; + } + + public EditorWindow getPrevWindow(@NotNull final EditorWindow window) { + final EditorWindow[] windows = getSplitters().getOrderedWindows(); + for (int i = 0; i != windows.length; ++i) { + if (windows[i].equals(window)) { + return windows[(i + windows.length - 1) % windows.length]; + } + } + LOG.error("Not window found"); + return null; + } + + public void createSplitter(final int orientation, @Nullable final EditorWindow window) { + // window was available from action event, for example when invoked from the tab menu of an editor that is not the 'current' + if (window != null) { + window.split(orientation, true, null, false); + } + // otherwise we'll split the current window, if any + else { + final EditorWindow currentWindow = getSplitters().getCurrentWindow(); + if (currentWindow != null) { + currentWindow.split(orientation, true, null, false); + } + } + } + + public void changeSplitterOrientation() { + final EditorWindow currentWindow = getSplitters().getCurrentWindow(); + if (currentWindow != null) { + currentWindow.changeOrientation(); + } + } + + + public void flipTabs() { + /* + if (myTabs == null) { + myTabs = new EditorTabs (this, UISettings.getInstance().EDITOR_TAB_PLACEMENT); + remove (mySplitters); + add (myTabs, BorderLayout.CENTER); + initTabs (); + } else { + remove (myTabs); + add (mySplitters, BorderLayout.CENTER); + myTabs.dispose (); + myTabs = null; + } + */ + myPanels.revalidate(); + } + + public boolean tabsMode() { + return false; + } + + private void setTabsMode(final boolean mode) { + if (tabsMode() != mode) { + flipTabs(); + } + //LOG.assertTrue (tabsMode () == mode); + } + + + public boolean isInSplitter() { + final EditorWindow currentWindow = getSplitters().getCurrentWindow(); + return currentWindow != null && currentWindow.inSplitter(); + } + + public boolean hasOpenedFile() { + final EditorWindow currentWindow = getSplitters().getCurrentWindow(); + return currentWindow != null && currentWindow.getSelectedEditor() != null; + } + + public VirtualFile getCurrentFile() { + return getActiveSplitters(true).getResult().getCurrentFile(); + } + + public AsyncResult getActiveWindow() { + return _getActiveWindow(false); + } + + private AsyncResult _getActiveWindow(boolean now) { + final AsyncResult result = new AsyncResult(); + getActiveSplitters(now).doWhenDone(new AsyncResult.Handler() { + @Override + public void run(EditorsSplitters editorsSplitters) { + result.setDone(editorsSplitters.getCurrentWindow()); + } + }); + + return result; + } + + public EditorWindow getCurrentWindow() { + return _getActiveWindow(true).getResult(); + } + + public void setCurrentWindow(final EditorWindow window) { + getActiveSplitters(true).getResult().setCurrentWindow(window, true); + } + + public void closeFile(@NotNull final VirtualFile file, @NotNull final EditorWindow window, final boolean transferFocus) { + assertDispatchThread(); + + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + if (window.isFileOpen(file)) { + window.closeFile(file, true, transferFocus); + final List windows = window.getOwner().findWindows(file); + if (windows.isEmpty()) { // no more windows containing this file left + final LocalFileSystem.WatchRequest request = file.getUserData(WATCH_REQUEST_KEY); + if (request != null) { + LocalFileSystem.getInstance().removeWatchedRoot(request); + } + } + } + } + }, IdeBundle.message("command.close.active.editor"), null); + removeSelectionRecord(file, window); + } + + public void closeFile(@NotNull final VirtualFile file, @NotNull final EditorWindow window) { + closeFile(file, window, true); + } + + //============================= EditorManager methods ================================ + + public void closeFile(@NotNull final VirtualFile file) { + closeFile(file, true, false); + } + + public void closeFile(@NotNull final VirtualFile file, final boolean moveFocus, final boolean closeAllCopies) { + assertDispatchThread(); + + final LocalFileSystem.WatchRequest request = file.getUserData(WATCH_REQUEST_KEY); + if (request != null) { + LocalFileSystem.getInstance().removeWatchedRoot(request); + } + + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + closeFileImpl(file, moveFocus, closeAllCopies); + } + }, "", null); + } + + + + private void closeFileImpl(@NotNull final VirtualFile file, final boolean moveFocus, boolean closeAllCopies) { + assertDispatchThread(); + runChange(new FileEditorManagerChange() { + public void run(EditorsSplitters splitters) { + splitters.closeFile(file, moveFocus); + } + }, closeAllCopies ? null : getActiveSplitters(true).getResult()); + } + + //-------------------------------------- Open File ---------------------------------------- + + @NotNull + public Pair openFileWithProviders(@NotNull final VirtualFile file, + final boolean focusEditor, + boolean searchForSplitter) { + if (!file.isValid()) { + throw new IllegalArgumentException("file is not valid: " + file); + } + assertDispatchThread(); + + EditorWindow wndToOpenIn = null; + if (searchForSplitter) { + Set all = getAllSplitters(); + EditorsSplitters active = getActiveSplitters(true).getResult(); + if (active.getCurrentWindow() != null && active.getCurrentWindow().isFileOpen(file)) { + wndToOpenIn = active.getCurrentWindow(); + } else { + for (EditorsSplitters splitters : all) { + final EditorWindow window = splitters.getCurrentWindow(); + if (window == null) continue; + + if (window.isFileOpen(file)) { + wndToOpenIn = window; + break; + } + } + } + } + else { + wndToOpenIn = getSplitters().getCurrentWindow(); + } + + EditorsSplitters splitters = getSplitters(); + + if (wndToOpenIn == null) { + wndToOpenIn = splitters.getOrCreateCurrentWindow(file); + } + + openAssociatedFile(file, wndToOpenIn, splitters); + return openFileImpl2(wndToOpenIn, file, focusEditor); + } + + private void openAssociatedFile(VirtualFile file, EditorWindow wndToOpenIn, EditorsSplitters splitters) { + EditorWindow[] windows = splitters.getWindows(); + + if (file != null && windows.length == 2) { + for (FileEditorAssociateFinder finder : Extensions.getExtensions(FileEditorAssociateFinder.EP_NAME)) { + VirtualFile associatedFile = finder.getAssociatedFileToOpen(myProject, file); + + if (associatedFile != null) { + EditorWindow currentWindow = splitters.getCurrentWindow(); + int idx = windows[0] == wndToOpenIn ? 1 : 0; + openFileImpl2(windows[idx], associatedFile, false); + + if (currentWindow != null) { + splitters.setCurrentWindow(currentWindow, false); + } + + break; + } + } + } + } + + @NotNull + @Override + public Pair openFileWithProviders(@NotNull VirtualFile file, + boolean focusEditor, + @NotNull EditorWindow window) { + if (!file.isValid()) { + throw new IllegalArgumentException("file is not valid: " + file); + } + assertDispatchThread(); + + return openFileImpl2(window, file, focusEditor); + } + + @NotNull + public Pair openFileImpl2(@NotNull final EditorWindow window, + @NotNull final VirtualFile file, + final boolean focusEditor) { + final Ref> result = new Ref>(); + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + result.set(openFileImpl3(window, file, focusEditor, null, true)); + } + }, "", null); + return result.get(); + } + + /** + * @param file to be opened. Unlike openFile method, file can be + * invalid. For example, all file were invalidate and they are being + * removed one by one. If we have removed one invalid file, then another + * invalid file become selected. That's why we do not require that + * passed file is valid. + * @param entry map between FileEditorProvider and FileEditorState. If this parameter + * @param current + */ + @NotNull + Pair openFileImpl3(@NotNull final EditorWindow window, + @NotNull final VirtualFile file, + final boolean focusEditor, + @Nullable final HistoryEntry entry, + boolean current) { + return openFileImpl4(window, file, focusEditor, entry, current, -1); + } + + @NotNull + Pair openFileImpl4(@NotNull final EditorWindow window, + @NotNull final VirtualFile file, + final boolean focusEditor, + @Nullable final HistoryEntry entry, + boolean current, + int index) { + // Open file + FileEditor[] editors; + FileEditorProvider[] providers; + final EditorWithProviderComposite newSelectedComposite; + boolean newEditorCreated = false; + + final boolean open = window.isFileOpen(file); + if (open) { + // File is already opened. In this case we have to just select existing EditorComposite + newSelectedComposite = window.findFileComposite(file); + LOG.assertTrue(newSelectedComposite != null); + + editors = newSelectedComposite.getEditors(); + providers = newSelectedComposite.getProviders(); + } + else { + // File is not opened yet. In this case we have to create editors + // and select the created EditorComposite. + final FileEditorProviderManager editorProviderManager = FileEditorProviderManager.getInstance(); + providers = editorProviderManager.getProviders(myProject, file); + if (DumbService.getInstance(myProject).isDumb()) { + final List dumbAware = ContainerUtil.findAll(providers, new Condition() { + public boolean value(FileEditorProvider fileEditorProvider) { + return DumbService.isDumbAware(fileEditorProvider); + } + }); + providers = dumbAware.toArray(new FileEditorProvider[dumbAware.size()]); + } + + if (providers.length == 0) { + return Pair.create(EMPTY_EDITOR_ARRAY, EMPTY_PROVIDER_ARRAY); + } + newEditorCreated = true; + + getProject().getMessageBus().syncPublisher(FileEditorManagerListener.Before.FILE_EDITOR_MANAGER).beforeFileOpened(this, file); + + editors = new FileEditor[providers.length]; + for (int i = 0; i < providers.length; i++) { + try { + final FileEditorProvider provider = providers[i]; + LOG.assertTrue(provider != null); + LOG.assertTrue(provider.accept(myProject, file)); + final FileEditor editor = provider.createEditor(myProject, file); + LOG.assertTrue(editor != null); + LOG.assertTrue(editor.isValid()); + editors[i] = editor; + // Register PropertyChangeListener into editor + editor.addPropertyChangeListener(myEditorPropertyChangeListener); + editor.putUserData(DUMB_AWARE, DumbService.isDumbAware(provider)); + + if (current && editor instanceof TextEditorImpl) { + ((TextEditorImpl)editor).initFolding(); + } + } + catch (Exception e) { + LOG.error(e); + } + catch (AssertionError e) { + LOG.error(e); + } + } + + // Now we have to create EditorComposite and insert it into the TabbedEditorComponent. + // After that we have to select opened editor. + newSelectedComposite = new EditorWithProviderComposite(file, editors, providers, this); + + if (index >= 0) { + newSelectedComposite.getFile().putUserData(EditorWindow.INITIAL_INDEX_KEY, index); + } + } + + window.setEditor(newSelectedComposite, focusEditor); + + final EditorHistoryManager editorHistoryManager = EditorHistoryManager.getInstance(myProject); + for (int i = 0; i < editors.length; i++) { + final FileEditor editor = editors[i]; + if (editor instanceof TextEditor) { + // hack!!! + // This code prevents "jumping" on next repaint. + ((EditorEx)((TextEditor)editor).getEditor()).stopOptimizedScrolling(); + } + + final FileEditorProvider provider = providers[i];//getProvider(editor); + + // Restore editor state + FileEditorState state = null; + if (entry != null) { + state = entry.getState(provider); + } + if (state == null && !open) { + // We have to try to get state from the history only in case + // if editor is not opened. Otherwise history entry might have a state + // out of sync with the current editor state. + state = editorHistoryManager.getState(file, provider); + } + if (state != null) { + editor.setState(state); + } + } + + // Restore selected editor + final FileEditorProvider selectedProvider = editorHistoryManager.getSelectedProvider(file); + if (selectedProvider != null) { + final FileEditor[] _editors = newSelectedComposite.getEditors(); + final FileEditorProvider[] _providers = newSelectedComposite.getProviders(); + for (int i = _editors.length - 1; i >= 0; i--) { + final FileEditorProvider provider = _providers[i];//getProvider(_editors[i]); + if (provider.equals(selectedProvider)) { + newSelectedComposite.setSelectedEditor(i); + break; + } + } + } + + // Notify editors about selection changes + window.getOwner().setCurrentWindow(window, focusEditor); + window.getOwner().afterFileOpen(file); + + newSelectedComposite.getSelectedEditor().selectNotify(); + + final IdeFocusManager focusManager = IdeFocusManager.getInstance(myProject); + if (newEditorCreated) { + if (window.isShowing()) { + window.setPaintBlocked(true); + } + notifyPublisher(new Runnable() { + @Override + public void run() { + window.setPaintBlocked(false); + if (isFileOpen(file)) { + getProject().getMessageBus().syncPublisher(FileEditorManagerListener.FILE_EDITOR_MANAGER) + .fileOpened(FileEditorManagerImpl.this, file); + } + } + }); + + //Add request to watch this editor's virtual file + final VirtualFile parentDir = file.getParent(); + if (parentDir != null) { + final LocalFileSystem.WatchRequest request = LocalFileSystem.getInstance().addRootToWatch(parentDir.getPath(), false); + file.putUserData(WATCH_REQUEST_KEY, request); + } + } + + //[jeka] this is a hack to support back-forward navigation + // previously here was incorrect call to fireSelectionChanged() with a side-effect + ((IdeDocumentHistoryImpl)IdeDocumentHistory.getInstance(myProject)).onSelectionChanged(); + + // Transfer focus into editor + if (!ApplicationManagerEx.getApplicationEx().isUnitTestMode()) { + if (focusEditor) { + //myFirstIsActive = myTabbedContainer1.equals(tabbedContainer); + window.setAsCurrentWindow(true); + ToolWindowManager.getInstance(myProject).activateEditorComponent(); + focusManager.toFront(window.getOwner()); + } + } + + // Update frame and tab title + updateFileName(file); + + // Make back/forward work + IdeDocumentHistory.getInstance(myProject).includeCurrentCommandAsNavigation(); + + return Pair.create(editors, providers); + } + + @Override + public ActionCallback notifyPublisher(final Runnable runnable) { + final IdeFocusManager focusManager = IdeFocusManager.getInstance(myProject); + final ActionCallback done = new ActionCallback(); + return myBusyObject.execute(new ActiveRunnable() { + @Override + public ActionCallback run() { + focusManager.doWhenFocusSettlesDown(new ExpirableRunnable.ForProject(myProject) { + @Override + public void run() { + runnable.run(); + done.setDone(); + } + }); + return done; + } + }); + } + + public void setSelectedEditor(VirtualFile file, String fileEditorProviderId) { + EditorWithProviderComposite composite = getCurrentEditorWithProviderComposite(file); + if (composite == null) { + final List composites = getEditorComposites(file); + + if (composites.isEmpty()) return; + composite = composites.get(0); + } + + final FileEditorProvider[] editorProviders = composite.getProviders(); + final FileEditorProvider selectedProvider = composite.getSelectedEditorWithProvider().getSecond(); + + for (int i = 0; i < editorProviders.length; i++) { + if (editorProviders[i].getEditorTypeId().equals(fileEditorProviderId) && !selectedProvider.equals(editorProviders[i])) { + composite.setSelectedEditor(i); + composite.getSelectedEditor().selectNotify(); + } + } + } + + + @Nullable + EditorWithProviderComposite newEditorComposite(final VirtualFile file) { + if (file == null) { + return null; + } + + final FileEditorProviderManager editorProviderManager = FileEditorProviderManager.getInstance(); + final FileEditorProvider[] providers = editorProviderManager.getProviders(myProject, file); + final FileEditor[] editors = new FileEditor[providers.length]; + for (int i = 0; i < providers.length; i++) { + final FileEditorProvider provider = providers[i]; + LOG.assertTrue(provider != null); + LOG.assertTrue(provider.accept(myProject, file)); + final FileEditor editor = provider.createEditor(myProject, file); + editors[i] = editor; + LOG.assertTrue(editor.isValid()); + editor.addPropertyChangeListener(myEditorPropertyChangeListener); + } + + final EditorWithProviderComposite newComposite = new EditorWithProviderComposite(file, editors, providers, this); + final EditorHistoryManager editorHistoryManager = EditorHistoryManager.getInstance(myProject); + for (int i = 0; i < editors.length; i++) { + final FileEditor editor = editors[i]; + if (editor instanceof TextEditor) { + // hack!!! + // This code prevents "jumping" on next repaint. + //((EditorEx)((TextEditor)editor).getEditor()).stopOptimizedScrolling(); + } + + final FileEditorProvider provider = providers[i]; + +// Restore myEditor state + FileEditorState state = editorHistoryManager.getState(file, provider); + if (state != null) { + editor.setState(state); + } + } + return newComposite; + } + + @NotNull + public List openEditor(@NotNull final OpenFileDescriptor descriptor, final boolean focusEditor) { + assertDispatchThread(); + if (descriptor.getFile() instanceof VirtualFileWindow) { + VirtualFileWindow delegate = (VirtualFileWindow)descriptor.getFile(); + int hostOffset = delegate.getDocumentWindow().injectedToHost(descriptor.getOffset()); + OpenFileDescriptor realDescriptor = new OpenFileDescriptor(descriptor.getProject(), delegate.getDelegate(), hostOffset); + realDescriptor.setUseCurrentWindow(descriptor.isUseCurrentWindow()); + return openEditor(realDescriptor, focusEditor); + } + + final List result = new ArrayList(); + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + VirtualFile file = descriptor.getFile(); + final FileEditor[] editors = openFile(file, focusEditor, !descriptor.isUseCurrentWindow()); + ContainerUtil.addAll(result, editors); + + boolean navigated = false; + for (final FileEditor editor : editors) { + if (editor instanceof NavigatableFileEditor && + getSelectedEditor(descriptor.getFile()) == editor) { // try to navigate opened editor + navigated = navigateAndSelectEditor((NavigatableFileEditor)editor, descriptor); + if (navigated) break; + } + } + + if (!navigated) { + for (final FileEditor editor : editors) { + if (editor instanceof NavigatableFileEditor && getSelectedEditor(descriptor.getFile()) != editor) { // try other editors + if (navigateAndSelectEditor((NavigatableFileEditor)editor, descriptor)) { + break; + } + } + } + } + } + }, "", null); + + return result; + } + + private boolean navigateAndSelectEditor(final NavigatableFileEditor editor, final OpenFileDescriptor descriptor) { + if (editor.canNavigateTo(descriptor)) { + setSelectedEditor(editor); + editor.navigateTo(descriptor); + return true; + } + + return false; + } + + private void setSelectedEditor(final FileEditor editor) { + final EditorWithProviderComposite composite = getEditorComposite(editor); + if (composite == null) return; + + final FileEditor[] editors = composite.getEditors(); + for (int i = 0; i < editors.length; i++) { + final FileEditor each = editors[i]; + if (editor == each) { + composite.setSelectedEditor(i); + composite.getSelectedEditor().selectNotify(); + break; + } + } + } + + @NotNull + public Project getProject() { + return myProject; + } + + @Nullable + public Editor openTextEditor(final OpenFileDescriptor descriptor, final boolean focusEditor) { + final Collection fileEditors = openEditor(descriptor, focusEditor); + for (FileEditor fileEditor : fileEditors) { + if (fileEditor instanceof TextEditor) { + setSelectedEditor(descriptor.getFile(), TextEditorProvider.getInstance().getEditorTypeId()); + Editor editor = ((TextEditor)fileEditor).getEditor(); + return getOpenedEditor(editor, focusEditor); + } + } + + return null; + } + + protected Editor getOpenedEditor(final Editor editor, final boolean focusEditor) { + return editor; + } + + public Editor getSelectedTextEditor() { + assertReadAccess(); + + final EditorWindow currentWindow = getSplitters().getCurrentWindow(); + if (currentWindow != null) { + final EditorWithProviderComposite selectedEditor = currentWindow.getSelectedEditor(); + if (selectedEditor != null && selectedEditor.getSelectedEditor() instanceof TextEditor) { + return ((TextEditor)selectedEditor.getSelectedEditor()).getEditor(); + } + } + + return null; + } + + + public boolean isFileOpen(@NotNull final VirtualFile file) { + return !getEditorComposites(file).isEmpty(); + } + + @NotNull + public VirtualFile[] getOpenFiles() { + HashSet openFiles = new HashSet(); + for (EditorsSplitters each : getAllSplitters()) { + openFiles.addAll(Arrays.asList(each.getOpenFiles())); + } + + return VfsUtilCore.toVirtualFileArray(openFiles); + } + + @NotNull + public VirtualFile[] getSelectedFiles() { + HashSet selectedFiles = new HashSet(); + for (EditorsSplitters each : getAllSplitters()) { + selectedFiles.addAll(Arrays.asList(each.getSelectedFiles())); + } + + return VfsUtilCore.toVirtualFileArray(selectedFiles); + } + + @NotNull + public FileEditor[] getSelectedEditors() { + HashSet selectedEditors = new HashSet(); + for (EditorsSplitters each : getAllSplitters()) { + selectedEditors.addAll(Arrays.asList(each.getSelectedEditors())); + } + + return selectedEditors.toArray(new FileEditor[selectedEditors.size()]); + } + + public EditorsSplitters getSplitters() { + EditorsSplitters active = getActiveSplitters(true).getResult(); + return active == null ? getMainSplitters() : active; + } + + @Nullable + public FileEditor getSelectedEditor(@NotNull final VirtualFile file) { + final Pair selectedEditorWithProvider = getSelectedEditorWithProvider(file); + return selectedEditorWithProvider == null ? null : selectedEditorWithProvider.getFirst(); + } + + + @Nullable + public Pair getSelectedEditorWithProvider(@NotNull VirtualFile file) { + if (file instanceof VirtualFileWindow) file = ((VirtualFileWindow)file).getDelegate(); + final EditorWithProviderComposite composite = getCurrentEditorWithProviderComposite(file); + if (composite != null) { + return composite.getSelectedEditorWithProvider(); + } + + final List composites = getEditorComposites(file); + return composites.isEmpty() ? null : composites.get(0).getSelectedEditorWithProvider(); + } + + @NotNull + public Pair getEditorsWithProviders(@NotNull final VirtualFile file) { + assertReadAccess(); + + final EditorWithProviderComposite composite = getCurrentEditorWithProviderComposite(file); + if (composite != null) { + return Pair.create(composite.getEditors(), composite.getProviders()); + } + + final List composites = getEditorComposites(file); + if (!composites.isEmpty()) { + return Pair.create(composites.get(0).getEditors(), composites.get(0).getProviders()); + } + else { + return Pair.create(EMPTY_EDITOR_ARRAY, EMPTY_PROVIDER_ARRAY); + } + } + + @NotNull + public FileEditor[] getEditors(@NotNull VirtualFile file) { + assertReadAccess(); + if (file instanceof VirtualFileWindow) file = ((VirtualFileWindow)file).getDelegate(); + + final EditorWithProviderComposite composite = getCurrentEditorWithProviderComposite(file); + if (composite != null) { + return composite.getEditors(); + } + + final List composites = getEditorComposites(file); + if (!composites.isEmpty()) { + return composites.get(0).getEditors(); + } + else { + return EMPTY_EDITOR_ARRAY; + } + } + + @NotNull + @Override + public FileEditor[] getAllEditors(@NotNull VirtualFile file) { + List editorComposites = getEditorComposites(file); + List editors = new ArrayList(); + for (EditorWithProviderComposite composite : editorComposites) { + ContainerUtil.addAll(editors, composite.getEditors()); + } + return editors.toArray(new FileEditor[editors.size()]); + } + + @Nullable + private EditorWithProviderComposite getCurrentEditorWithProviderComposite(@NotNull final VirtualFile virtualFile) { + final EditorWindow editorWindow = getSplitters().getCurrentWindow(); + if (editorWindow != null) { + return editorWindow.findFileComposite(virtualFile); + } + return null; + } + + @NotNull + public List getEditorComposites(final VirtualFile file) { + ArrayList result = new ArrayList(); + Set all = getAllSplitters(); + for (EditorsSplitters each : all) { + result.addAll(each.findEditorComposites(file)); + } + return result; + } + + @NotNull + public FileEditor[] getAllEditors() { + assertReadAccess(); + final ArrayList result = new ArrayList(); + final Set allSplitters = getAllSplitters(); + for (EditorsSplitters splitter : allSplitters) { + final EditorWithProviderComposite[] editorsComposites = splitter.getEditorsComposites(); + for (EditorWithProviderComposite editorsComposite : editorsComposites) { + final FileEditor[] editors = editorsComposite.getEditors(); + ContainerUtil.addAll(result, editors); + } + } + return result.toArray(new FileEditor[result.size()]); + } + + public void showEditorAnnotation(@NotNull FileEditor editor, @NotNull JComponent annotationComponent) { + addTopComponent(editor, annotationComponent); + } + + public void removeEditorAnnotation(@NotNull FileEditor editor, @NotNull JComponent annotationComponent) { + removeTopComponent(editor, annotationComponent); + } + + public void addTopComponent(@NotNull final FileEditor editor, @NotNull final JComponent component) { + final EditorComposite composite = getEditorComposite(editor); + if (composite != null) { + composite.addTopComponent(editor, component); + } + } + + public void removeTopComponent(@NotNull final FileEditor editor, @NotNull final JComponent component) { + final EditorComposite composite = getEditorComposite(editor); + if (composite != null) { + composite.removeTopComponent(editor, component); + } + } + + public void addBottomComponent(@NotNull final FileEditor editor, @NotNull final JComponent component) { + final EditorComposite composite = getEditorComposite(editor); + if (composite != null) { + composite.addBottomComponent(editor, component); + } + } + + public void removeBottomComponent(@NotNull final FileEditor editor, @NotNull final JComponent component) { + final EditorComposite composite = getEditorComposite(editor); + if (composite != null) { + composite.removeBottomComponent(editor, component); + } + } + + private final MessageListenerList myListenerList; + + public void addFileEditorManagerListener(@NotNull final FileEditorManagerListener listener) { + myListenerList.add(listener); + } + + public void addFileEditorManagerListener(@NotNull final FileEditorManagerListener listener, final Disposable parentDisposable) { + myListenerList.add(listener, parentDisposable); + } + + public void removeFileEditorManagerListener(@NotNull final FileEditorManagerListener listener) { + myListenerList.remove(listener); + } + +// ProjectComponent methods + + public void projectOpened() { + //myFocusWatcher.install(myWindows.getComponent ()); + getMainSplitters().startListeningFocus(); + + MessageBusConnection connection = myProject.getMessageBus().connect(myProject); + + final FileStatusManager fileStatusManager = FileStatusManager.getInstance(myProject); + if (fileStatusManager != null) { + /** + * Updates tabs colors + */ + final MyFileStatusListener myFileStatusListener = new MyFileStatusListener(); + fileStatusManager.addFileStatusListener(myFileStatusListener, myProject); + } + connection.subscribe(FileTypeManager.TOPIC, new MyFileTypeListener()); + connection.subscribe(ProjectTopics.PROJECT_ROOTS, new MyRootsListener()); + + /** + * Updates tabs names + */ + final MyVirtualFileListener myVirtualFileListener = new MyVirtualFileListener(); + VirtualFileManager.getInstance().addVirtualFileListener(myVirtualFileListener, myProject); + /** + * Extends/cuts number of opened tabs. Also updates location of tabs. + */ + final MyUISettingsListener myUISettingsListener = new MyUISettingsListener(); + UISettings.getInstance().addUISettingsListener(myUISettingsListener, myProject); + + StartupManager.getInstance(myProject).registerPostStartupActivity(new DumbAwareRunnable() { + public void run() { + + setTabsMode(UISettings.getInstance().EDITOR_TAB_PLACEMENT != UISettings.TABS_NONE); + + ToolWindowManager.getInstance(myProject).invokeLater(new Runnable() { + public void run() { + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + + LaterInvocator.invokeLater(new Runnable() { + public void run() { + long currentTime = System.nanoTime(); + Long startTime = myProject.getUserData(ProjectImpl.CREATION_TIME); + if (startTime != null) { + LOG.info("Project opening took " + (currentTime - startTime.longValue()) / 1000000 + " ms"); + PluginManager.dumpPluginClassStatistics(); + } + } + }); +// group 1 + } + }, "", null); + } + }); + } + }); + } + + public void projectClosed() { + //myFocusWatcher.deinstall(myWindows.getComponent ()); + getMainSplitters().dispose(); + +// Dispose created editors. We do not use use closeEditor method because +// it fires event and changes history. + closeAllFiles(); + } + +// BaseCompomemnt methods + + @NotNull + public String getComponentName() { + return "FileEditorManager"; + } + + public void initComponent() { + + } + + public void disposeComponent() { /* really do nothing */ } + +//JDOMExternalizable methods + + public void writeExternal(final Element element) { + getMainSplitters().writeExternal(element); + } + + public void readExternal(final Element element) { + getMainSplitters().readExternal(element); + } + + @Nullable + private EditorWithProviderComposite getEditorComposite(@NotNull final FileEditor editor) { + for (EditorsSplitters splitters : getAllSplitters()) { + final EditorWithProviderComposite[] editorsComposites = splitters.getEditorsComposites(); + for (int i = editorsComposites.length - 1; i >= 0; i--) { + final EditorWithProviderComposite composite = editorsComposites[i]; + final FileEditor[] editors = composite.getEditors(); + for (int j = editors.length - 1; j >= 0; j--) { + final FileEditor _editor = editors[j]; + LOG.assertTrue(_editor != null); + if (editor.equals(_editor)) { + return composite; + } + } + } + } + return null; + } + +//======================= Misc ===================== + + private static void assertDispatchThread() { + ApplicationManager.getApplication().assertIsDispatchThread(); + } + + private static void assertReadAccess() { + ApplicationManager.getApplication().assertReadAccessAllowed(); + } + + public void fireSelectionChanged(final EditorComposite newSelectedComposite) { + final Trinity oldData = extract(myLastSelectedComposite.get()); + final Trinity newData = extract(newSelectedComposite); + myLastSelectedComposite = new WeakReference(newSelectedComposite); + final boolean filesEqual = oldData.first == null ? newData.first == null : oldData.first.equals(newData.first); + final boolean editorsEqual = oldData.second == null ? newData.second == null : oldData.second.equals(newData.second); + if (!filesEqual || !editorsEqual) { + if (oldData.first != null && newData.first != null) { + for (FileEditorAssociateFinder finder : Extensions.getExtensions(FileEditorAssociateFinder.EP_NAME)) { + VirtualFile associatedFile = finder.getAssociatedFileToOpen(myProject, oldData.first); + + if (Comparing.equal(associatedFile, newData.first)) { + return; + } + } + } + + final FileEditorManagerEvent event = + new FileEditorManagerEvent(this, oldData.first, oldData.second, oldData.third, newData.first, newData.second, newData.third); + final FileEditorManagerListener publisher = getProject().getMessageBus().syncPublisher(FileEditorManagerListener.FILE_EDITOR_MANAGER); + + if (newData.first != null) { + final JComponent component = newData.second.getComponent(); + final EditorWindowHolder holder = UIUtil.getParentOfType(EditorWindowHolder.class, component); + if (holder != null) { + addSelectionRecord(newData.first, holder.getEditorWindow()); + } + } + notifyPublisher(new Runnable() { + @Override + public void run() { + publisher.selectionChanged(event); + } + }); + } + } + + @NotNull + private static Trinity extract(@Nullable EditorComposite composite) { + final VirtualFile file; + final FileEditor editor; + final FileEditorProvider provider; + if (composite == null || composite.isDisposed()) { + file = null; + editor = null; + provider = null; + } + else { + file = composite.getFile(); + final Pair pair = composite.getSelectedEditorWithProvider(); + editor = pair.first; + provider = pair.second; + } + return new Trinity(file, editor, provider); + } + + public boolean isChanged(@NotNull final EditorComposite editor) { + final FileStatusManager fileStatusManager = FileStatusManager.getInstance(myProject); + if (fileStatusManager != null) { + VirtualFile file = editor.getFile(); + FileStatus status = fileStatusManager.getStatus(file); + if (status == FileStatus.UNKNOWN && !file.isWritable()) { + return false; + } + if (!status.equals(FileStatus.NOT_CHANGED)) { + return true; + } + } + return false; + } + + public void disposeComposite(@NotNull EditorWithProviderComposite editor) { + if (getAllEditors().length == 0) { + setCurrentWindow(null); + } + + if (editor.equals(getLastSelected())) { + editor.getSelectedEditor().deselectNotify(); + getSplitters().setCurrentWindow(null, false); + } + + final FileEditor[] editors = editor.getEditors(); + final FileEditorProvider[] providers = editor.getProviders(); + + final FileEditor selectedEditor = editor.getSelectedEditor(); + for (int i = editors.length - 1; i >= 0; i--) { + final FileEditor editor1 = editors[i]; + final FileEditorProvider provider = providers[i]; + if (!editor.equals(selectedEditor)) { // we already notified the myEditor (when fire event) + if (selectedEditor.equals(editor1)) { + editor1.deselectNotify(); + } + } + editor1.removePropertyChangeListener(myEditorPropertyChangeListener); + provider.disposeEditor(editor1); + } + + Disposer.dispose(editor); + } + + @Nullable + EditorComposite getLastSelected() { + final EditorWindow currentWindow = getActiveSplitters(true).getResult().getCurrentWindow(); + if (currentWindow != null) { + return currentWindow.getSelectedEditor(); + } + return null; + } + + public void runChange(FileEditorManagerChange change, EditorsSplitters splitters) { + Set target = new HashSet(); + if (splitters == null) { + target.addAll(getAllSplitters()); + } else { + target.add(splitters); + } + + for (EditorsSplitters each : target) { + each.myInsideChange++; + try { + change.run(each); + } + finally { + each.myInsideChange--; + } + } + } + + //================== Listeners ===================== + + /** + * Closes deleted files. Closes file which are in the deleted directories. + */ + private final class MyVirtualFileListener extends VirtualFileAdapter { + public void beforeFileDeletion(VirtualFileEvent e) { + assertDispatchThread(); + + boolean moveFocus = moveFocusOnDelete(); + + final VirtualFile file = e.getFile(); + final VirtualFile[] openFiles = getOpenFiles(); + for (int i = openFiles.length - 1; i >= 0; i--) { + if (VfsUtilCore.isAncestor(file, openFiles[i], false)) { + closeFile(openFiles[i], moveFocus, true); + } + } + } + + public void propertyChanged(VirtualFilePropertyEvent e) { + if (VirtualFile.PROP_NAME.equals(e.getPropertyName())) { + assertDispatchThread(); + final VirtualFile file = e.getFile(); + if (isFileOpen(file)) { + updateFileName(file); + updateFileIcon(file); // file type can change after renaming + updateFileBackgroundColor(file); + } + } + else if (VirtualFile.PROP_WRITABLE.equals(e.getPropertyName()) || VirtualFile.PROP_ENCODING.equals(e.getPropertyName())) { + // TODO: message bus? + updateIconAndStatusBar(e); + } + } + + private void updateIconAndStatusBar(final VirtualFilePropertyEvent e) { + assertDispatchThread(); + final VirtualFile file = e.getFile(); + if (isFileOpen(file)) { + updateFileIcon(file); + if (file.equals(getSelectedFiles()[0])) { // update "write" status + final StatusBarEx statusBar = (StatusBarEx)WindowManager.getInstance().getStatusBar(myProject); + assert statusBar != null; + statusBar.updateWidgets(); + } + } + } + + public void fileMoved(VirtualFileMoveEvent e) { + final VirtualFile file = e.getFile(); + final VirtualFile[] openFiles = getOpenFiles(); + for (final VirtualFile openFile : openFiles) { + if (VfsUtilCore.isAncestor(file, openFile, false)) { + updateFileName(openFile); + updateFileBackgroundColor(openFile); + } + } + } + } + + private static boolean moveFocusOnDelete() { + final Window window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow(); + if (window != null) { + final Component component = FocusTrackback.getFocusFor(window); + if (component != null) { + return component instanceof EditorComponentImpl; + } + return window instanceof IdeFrameImpl; + } + return true; + } + + public boolean isInsideChange() { + return getSplitters().isInsideChange(); + } + + private final class MyEditorPropertyChangeListener implements PropertyChangeListener { + public void propertyChange(final PropertyChangeEvent e) { + assertDispatchThread(); + + final String propertyName = e.getPropertyName(); + if (FileEditor.PROP_MODIFIED.equals(propertyName)) { + final FileEditor editor = (FileEditor)e.getSource(); + final EditorComposite composite = getEditorComposite(editor); + if (composite != null) { + updateFileIcon(composite.getFile()); + } + } + else if (FileEditor.PROP_VALID.equals(propertyName)) { + final boolean valid = ((Boolean)e.getNewValue()).booleanValue(); + if (!valid) { + final FileEditor editor = (FileEditor)e.getSource(); + LOG.assertTrue(editor != null); + final EditorComposite composite = getEditorComposite(editor); + if (composite != null) { + closeFile(composite.getFile()); + } + } + } + + } + } + + + /** + * Gets events from VCS and updates color of myEditor tabs + */ + private final class MyFileStatusListener implements FileStatusListener { + public void fileStatusesChanged() { // update color of all open files + assertDispatchThread(); + LOG.debug("FileEditorManagerImpl.MyFileStatusListener.fileStatusesChanged()"); + final VirtualFile[] openFiles = getOpenFiles(); + for (int i = openFiles.length - 1; i >= 0; i--) { + final VirtualFile file = openFiles[i]; + LOG.assertTrue(file != null); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (LOG.isDebugEnabled()) { + LOG.debug("updating file status in tab for " + file.getPath()); + } + updateFileStatus(file); + } + }, ModalityState.NON_MODAL, myProject.getDisposed()); + } + } + + public void fileStatusChanged(@NotNull final VirtualFile file) { // update color of the file (if necessary) + assertDispatchThread(); + if (isFileOpen(file)) { + updateFileStatus(file); + } + } + + private void updateFileStatus(final VirtualFile file) { + updateFileColor(file); + updateFileIcon(file); + } + } + + /** + * Gets events from FileTypeManager and updates icons on tabs + */ + private final class MyFileTypeListener implements FileTypeListener { + public void beforeFileTypesChanged(FileTypeEvent event) { + } + + public void fileTypesChanged(final FileTypeEvent event) { + assertDispatchThread(); + final VirtualFile[] openFiles = getOpenFiles(); + for (int i = openFiles.length - 1; i >= 0; i--) { + final VirtualFile file = openFiles[i]; + LOG.assertTrue(file != null); + updateFileIcon(file); + } + } + } + + private class MyRootsListener extends ModuleRootAdapter { + public void rootsChanged(ModuleRootEvent event) { + EditorFileSwapper[] swappers = Extensions.getExtensions(EditorFileSwapper.EP_NAME); + + for (EditorWindow eachWindow : getWindows()) { + EditorWithProviderComposite selected = eachWindow.getSelectedEditor(); + EditorWithProviderComposite[] editors = eachWindow.getEditors(); + for (int i = 0; i < editors.length; i++) { + EditorWithProviderComposite editor = editors[i]; + VirtualFile file = editor.getFile(); + if (!file.isValid()) continue; + + Pair newFilePair = null; + + for (EditorFileSwapper each : swappers) { + newFilePair = each.getFileToSwapTo(myProject, editor); + if (newFilePair != null) break; + } + + if (newFilePair == null) continue; + + VirtualFile newFile = newFilePair.first; + if (newFile == null) continue; + + // already open + if (eachWindow.findFileIndex(newFile) != -1) continue; + + try { + newFile.putUserData(EditorWindow.INITIAL_INDEX_KEY, i); + Pair pair = openFileImpl2(eachWindow, newFile, editor == selected); + + if (newFilePair.second != null) { + TextEditorImpl openedEditor = EditorFileSwapper.findSinglePsiAwareEditor(pair.first); + if (openedEditor != null) { + openedEditor.getEditor().getCaretModel().moveToOffset(newFilePair.second); + openedEditor.getEditor().getScrollingModel().scrollToCaret(ScrollType.CENTER); + } + } + } + finally { + newFile.putUserData(EditorWindow.INITIAL_INDEX_KEY, null); + } + closeFile(file, eachWindow); + } + } + } + } + + /** + * Gets notifications from UISetting component to track changes of RECENT_FILES_LIMIT + * and EDITOR_TAB_LIMIT, etc values. + */ + private final class MyUISettingsListener implements UISettingsListener { + public void uiSettingsChanged(final UISettings source) { + assertDispatchThread(); + setTabsMode(source.EDITOR_TAB_PLACEMENT != UISettings.TABS_NONE); + + for (EditorsSplitters each : getAllSplitters()) { + each.setTabsPlacement(source.EDITOR_TAB_PLACEMENT); + each.trimToSize(source.EDITOR_TAB_LIMIT); + + // Tab layout policy + if (source.SCROLL_TAB_LAYOUT_IN_EDITOR) { + each.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); + } + else { + each.setTabLayoutPolicy(JTabbedPane.WRAP_TAB_LAYOUT); + } + } + + // "Mark modified files with asterisk" + final VirtualFile[] openFiles = getOpenFiles(); + for (int i = openFiles.length - 1; i >= 0; i--) { + final VirtualFile file = openFiles[i]; + updateFileIcon(file); + updateFileName(file); + updateFileBackgroundColor(file); + } + } + } + + public void closeAllFiles() { + final VirtualFile[] openFiles = getSplitters().getOpenFiles(); + for (VirtualFile openFile : openFiles) { + closeFile(openFile); + } + } + + @NotNull + public VirtualFile[] getSiblings(VirtualFile file) { + return getOpenFiles(); + } + + protected void queueUpdateFile(final VirtualFile file) { + myQueue.queue(new Update(file) { + public void run() { + if (isFileOpen(file)) { + updateFileIcon(file); + updateFileColor(file); + updateFileBackgroundColor(file); + } + + } + }); + } + + public EditorsSplitters getSplittersFor(Component c) { + EditorsSplitters splitters = null; + DockContainer dockContainer = myDockManager.getContainerFor(c); + if (dockContainer instanceof DockableEditorTabbedContainer) { + splitters = ((DockableEditorTabbedContainer)dockContainer).getSplitters(); + } + + if (splitters == null) { + splitters = getMainSplitters(); + } + + return splitters; + } + + public List> getSelectionHistory() { + List> copy = new ArrayList>(); + for (Pair pair : mySelectionHistory) { + if (pair.second.getFiles().length == 0) { + final EditorWindow[] windows = pair.second.getOwner().getWindows(); + if (windows.length > 0 && windows[0] != null && windows[0].getFiles().length > 0) { + final Pair p = Pair.create(pair.first, windows[0]); + if (!copy.contains(p)) { + copy.add(p); + } + } + } else { + if (!copy.contains(pair)) { + copy.add(pair); + } + } + } + mySelectionHistory.clear(); + mySelectionHistory.addAll(copy); + return mySelectionHistory; + } + + public void addSelectionRecord(VirtualFile file, EditorWindow window) { + final Pair record = Pair.create(file, window); + mySelectionHistory.remove(record); + mySelectionHistory.add(0, record); + } + + public void removeSelectionRecord(VirtualFile file, EditorWindow window) { + mySelectionHistory.remove(Pair.create(file, window)); + } + + @Override + public ActionCallback getReady(@NotNull Object requestor) { + return myBusyObject.getReady(requestor); + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/vcs/impl/FileStatusManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vcs/impl/FileStatusManagerImpl.java index f8bd9fab1dea..04bdb84197fa 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vcs/impl/FileStatusManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vcs/impl/FileStatusManagerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * 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. @@ -36,6 +36,7 @@ import com.intellij.openapi.vcs.FileStatus; import com.intellij.openapi.vcs.FileStatusListener; import com.intellij.openapi.vcs.FileStatusManager; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.testFramework.LightVirtualFile; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NotNull; @@ -50,7 +51,6 @@ import java.util.Map; */ public class FileStatusManagerImpl extends FileStatusManager implements ProjectComponent { private final Map myCachedStatuses = Collections.synchronizedMap(new HashMap()); - private final Project myProject; private final List myListeners = ContainerUtil.createEmptyCOWList(); private FileStatusProvider myFileStatusProvider; @@ -123,7 +123,11 @@ public class FileStatusManagerImpl extends FileStatusManager implements ProjectC } } }; - EditorFactory.getInstance().getEventMulticaster().addDocumentListener(documentListener, myProject); + + final EditorFactory factory = EditorFactory.getInstance(); + if (factory != null) { + factory.getEventMulticaster().addDocumentListener(documentListener, myProject); + } } public void disposeComponent() { @@ -138,9 +142,7 @@ public class FileStatusManagerImpl extends FileStatusManager implements ProjectC public void initComponent() { } public void addFileStatusListener(@NotNull FileStatusListener listener) { - if (listener != null) { - myListeners.add(listener); - } + myListeners.add(listener); } public void addFileStatusListener(final FileStatusListener listener, Disposable parentDisposable) { @@ -202,6 +204,10 @@ public class FileStatusManagerImpl extends FileStatusManager implements ProjectC } public FileStatus getStatus(final VirtualFile file) { + if (file instanceof LightVirtualFile) { + return FileStatus.NOT_CHANGED; // do not leak light files via cache + } + FileStatus status = getCachedStatus(file); if (status == null || status == FileStatusNull.INSTANCE) { status = calcStatus(file); @@ -224,5 +230,4 @@ public class FileStatusManagerImpl extends FileStatusManager implements ProjectC myFileStatusProvider.refreshFileStatusFromDocument(file, doc); } } - } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java index 9a192273b04a..748fd7ed36a6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java @@ -17,6 +17,7 @@ package com.intellij.openapi.vfs.impl; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.*; import com.intellij.openapi.util.io.FileUtil; @@ -27,7 +28,10 @@ import com.intellij.openapi.vfs.ex.VirtualFileManagerEx; import com.intellij.openapi.vfs.ex.temp.TempFileSystem; import com.intellij.openapi.vfs.newvfs.BulkFileListener; import com.intellij.openapi.vfs.newvfs.events.*; -import com.intellij.openapi.vfs.pointers.*; +import com.intellij.openapi.vfs.pointers.VirtualFilePointer; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerContainer; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerListener; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.messages.MessageBus; @@ -41,11 +45,11 @@ import org.jetbrains.annotations.TestOnly; import java.util.*; -public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager implements ModificationTracker, BulkFileListener { +public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager implements ApplicationComponent, ModificationTracker, BulkFileListener { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl"); - private static final TempFileSystem TEMP_FILE_SYSTEM = TempFileSystem.getInstance(); - private static final LocalFileSystem LOCAL_FILE_SYSTEM = LocalFileSystem.getInstance(); - private static final JarFileSystem JAR_FILE_SYSTEM = JarFileSystem.getInstance(); + private final TempFileSystem TEMP_FILE_SYSTEM; + private final LocalFileSystem LOCAL_FILE_SYSTEM; + private final JarFileSystem JAR_FILE_SYSTEM; private long myVfsModificationCounter; // guarded by this private final Map myPointers = new LinkedHashMap(); @@ -67,10 +71,17 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp } }; - VirtualFilePointerManagerImpl(@NotNull VirtualFileManagerEx virtualFileManagerEx, @NotNull MessageBus bus) { + VirtualFilePointerManagerImpl(@NotNull VirtualFileManagerEx virtualFileManagerEx, + @NotNull MessageBus bus, + @NotNull TempFileSystem tempFileSystem, + @NotNull LocalFileSystem localFileSystem, + @NotNull JarFileSystem jarFileSystem) { myVirtualFileManager = virtualFileManagerEx; myBus = bus; bus.connect().subscribe(VirtualFileManager.VFS_CHANGES, this); + TEMP_FILE_SYSTEM = tempFileSystem; + LOCAL_FILE_SYSTEM = localFileSystem; + JAR_FILE_SYSTEM = jarFileSystem; } @@ -79,6 +90,20 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp return myVfsModificationCounter; } + @Override + public void initComponent() { + } + + @Override + public void disposeComponent() { + } + + @NotNull + @Override + public String getComponentName() { + return "VirtualFilePointerManager"; + } + private static class EventDescriptor { @NotNull private final VirtualFilePointerListener myListener; @NotNull private final VirtualFilePointer[] myPointers; diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java index dd7f84436da4..e07854bc140c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.vfs.newvfs.persistent; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VfsUtil; @@ -67,7 +68,7 @@ public class RefreshWorker { final VirtualFileSystemEntry file = (VirtualFileSystemEntry)myRefreshQueue.pullFirst(); if (!file.isDirty()) continue; - int attributes = file == root ? rootAttributes : delegate.getBooleanAttributes(file, -1); + int attributes = Comparing.equal(file, root) ? rootAttributes : delegate.getBooleanAttributes(file, -1); VirtualFileSystemEntry parent = file.getParent(); if (parent != null && checkAndScheduleAttributesChange(parent, file, delegate, attributes)) { // ignore everything else diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index dc9af1bf026d..b9a32b2443c2 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -13,8 +13,6 @@ - diff --git a/platform/platform-resources/src/componentSets/Platform.xml b/platform/platform-resources/src/componentSets/Platform.xml index 622c78db99b9..127f417d03ca 100644 --- a/platform/platform-resources/src/componentSets/Platform.xml +++ b/platform/platform-resources/src/componentSets/Platform.xml @@ -20,6 +20,11 @@ com.intellij.openapi.vfs.impl.VirtualFileManagerImpl + + com.intellij.openapi.vfs.pointers.VirtualFilePointerManager + com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl + + com.intellij.openapi.vfs.newvfs.ManagingFS com.intellij.openapi.vfs.newvfs.persistent.PersistentFS diff --git a/platform/platform-tests/testSrc/com/intellij/history/integration/IntegrationTestCase.java b/platform/platform-tests/testSrc/com/intellij/history/integration/IntegrationTestCase.java index 8c339dbfadc5..bca4cc9b34c0 100644 --- a/platform/platform-tests/testSrc/com/intellij/history/integration/IntegrationTestCase.java +++ b/platform/platform-tests/testSrc/com/intellij/history/integration/IntegrationTestCase.java @@ -30,6 +30,7 @@ import com.intellij.openapi.roots.ContentEntry; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.util.Clock; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.*; @@ -177,7 +178,7 @@ public abstract class IntegrationTestCase extends PlatformTestCase { ModuleRootManager rm = ModuleRootManager.getInstance(myModule); ModifiableRootModel m = rm.getModifiableModel(); for (ContentEntry e : m.getContentEntries()) { - if (e.getFile() != myRoot) continue; + if (!Comparing.equal(e.getFile(), myRoot)) continue; e.addExcludeFolder(VfsUtilCore.pathToUrl(FileUtil.toSystemIndependentName(path))); } m.commit(); diff --git a/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java b/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java index d29cbdda2a1b..312bedd68b28 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java +++ b/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java @@ -31,6 +31,7 @@ import com.intellij.openapi.roots.impl.ContentEntryImpl; import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.*; @@ -189,7 +190,7 @@ public class PsiTestUtil { } }.execute().throwException(); for (ContentEntry entry : rootManager.getContentEntries()) { - if (entry.getFile() == vDir) { + if (Comparing.equal(entry.getFile(), vDir)) { Assert.assertFalse(((ContentEntryImpl)entry).isDisposed()); return entry; } diff --git a/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java b/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java index 6e84ee8c0c03..025217bdc4df 100644 --- a/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java +++ b/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java @@ -308,7 +308,7 @@ public class UsageInfo2UsageAdapter implements UsageInModule, if (!(other instanceof UsageInfo2UsageAdapter)) return false; UsageInfo2UsageAdapter u2 = (UsageInfo2UsageAdapter)other; assert u2 != this; - if (myLineNumber != u2.myLineNumber || getFile() != u2.getFile()) return false; + if (myLineNumber != u2.myLineNumber || !Comparing.equal(getFile(), u2.getFile())) return false; myMergedUsageInfos.addAll(u2.myMergedUsageInfos); Collections.sort(myMergedUsageInfos, new Comparator() { @Override diff --git a/platform/util-rt/src/com/intellij/openapi/util/Pair.java b/platform/util-rt/src/com/intellij/openapi/util/Pair.java index 2057525a41cb..ce63e207fcfa 100644 --- a/platform/util-rt/src/com/intellij/openapi/util/Pair.java +++ b/platform/util-rt/src/com/intellij/openapi/util/Pair.java @@ -22,7 +22,7 @@ public class Pair { public final A first; public final B second; - public static Pair create(@Nullable A first, @Nullable B second) { + public static Pair create(A first, B second) { return new Pair(first, second); } @@ -52,17 +52,15 @@ public class Pair { return EMPTY; } - public Pair(@Nullable A first, @Nullable B second) { + public Pair(A first, B second) { this.first = first; this.second = second; } - - @Nullable + public final A getFirst() { return first; } - @Nullable public final B getSecond() { return second; } diff --git a/platform/util/src/com/intellij/openapi/util/Key.java b/platform/util/src/com/intellij/openapi/util/Key.java index 4412b3827be7..8a0b388a25c6 100644 --- a/platform/util/src/com/intellij/openapi/util/Key.java +++ b/platform/util/src/com/intellij/openapi/util/Key.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.util; +import com.intellij.util.containers.ConcurrentWeakValueHashMap; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -33,9 +34,11 @@ public class Key { private static final AtomicInteger ourKeysCounter = new AtomicInteger(); private final int myIndex = ourKeysCounter.getAndIncrement(); private final String myName; // for debug purposes only + private static final ConcurrentWeakValueHashMap allKeys = new ConcurrentWeakValueHashMap(); public Key(@NotNull @NonNls String name) { myName = name; + allKeys.put(myIndex, this); } public final int hashCode() { @@ -62,6 +65,7 @@ public class Key { @Nullable public T get(@Nullable Map holder) { + //noinspection unchecked return holder == null ? null : (T)holder.get(this); } @@ -93,4 +97,9 @@ public class Key { holder.put(this, value); } } + + public static Key getKeyByIndex(int index) { + //noinspection unchecked + return (Key)allKeys.get(index); + } } \ No newline at end of file diff --git a/platform/util/src/com/intellij/openapi/util/UserDataHolderBase.java b/platform/util/src/com/intellij/openapi/util/UserDataHolderBase.java index 01f2d081612b..1f1b0b475a94 100644 --- a/platform/util/src/com/intellij/openapi/util/UserDataHolderBase.java +++ b/platform/util/src/com/intellij/openapi/util/UserDataHolderBase.java @@ -16,39 +16,37 @@ package com.intellij.openapi.util; -import com.intellij.util.SmartFMap; import com.intellij.util.concurrency.AtomicFieldUpdater; +import com.intellij.util.keyFMap.KeyFMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; -import java.util.Map; - public class UserDataHolderBase implements UserDataHolderEx, Cloneable { - private static final Key> COPYABLE_USER_MAP_KEY = Key.create("COPYABLE_USER_MAP_KEY"); + public static final Key COPYABLE_USER_MAP_KEY = Key.create("COPYABLE_USER_MAP_KEY"); /** * Concurrent writes to this field are via CASes only, using the {@link #updater} */ - @NotNull private volatile SmartFMap myUserMap = SmartFMap.emptyMap(); + @NotNull private volatile KeyFMap myUserMap = KeyFMap.EMPTY_MAP; + @Override protected Object clone() { try { UserDataHolderBase clone = (UserDataHolderBase)super.clone(); - clone.myUserMap = SmartFMap.emptyMap(); + clone.myUserMap = KeyFMap.EMPTY_MAP; copyCopyableDataTo(clone); return clone; } catch (CloneNotSupportedException e) { throw new RuntimeException(e); - } } @TestOnly public String getUserDataString() { - final SmartFMap userMap = myUserMap; - final Map copyableMap = getUserData(COPYABLE_USER_MAP_KEY); + final KeyFMap userMap = myUserMap; + final KeyFMap copyableMap = getUserData(COPYABLE_USER_MAP_KEY); return userMap.toString() + (copyableMap == null ? "" : copyableMap.toString()); } @@ -56,64 +54,68 @@ public class UserDataHolderBase implements UserDataHolderEx, Cloneable { other.myUserMap = myUserMap; } + @Override public T getUserData(@NotNull Key key) { //noinspection unchecked - return (T)myUserMap.get(key); + return myUserMap.get(key); } + @Override public void putUserData(@NotNull Key key, @Nullable T value) { while (true) { - SmartFMap map = myUserMap; - SmartFMap newMap = value == null ? map.minus(key) : map.plus(key, value); + KeyFMap map = myUserMap; + KeyFMap newMap = value == null ? map.minus(key) : map.plus(key, value); if (newMap == map || updater.compareAndSet(this, map, newMap)) { - return; + break; } } } public T getCopyableUserData(Key key) { - SmartFMap map = getUserData(COPYABLE_USER_MAP_KEY); + KeyFMap map = getUserData(COPYABLE_USER_MAP_KEY); //noinspection unchecked,ConstantConditions - return map == null ? null : (T)map.get(key); + return map == null ? null : map.get(key); } public void putCopyableUserData(Key key, T value) { while (true) { - SmartFMap map = myUserMap; - @SuppressWarnings("unchecked") SmartFMap copyableMap = (SmartFMap)map.get(COPYABLE_USER_MAP_KEY); + KeyFMap map = myUserMap; + KeyFMap copyableMap = map.get(COPYABLE_USER_MAP_KEY); if (copyableMap == null) { - copyableMap = SmartFMap.emptyMap(); + copyableMap = KeyFMap.EMPTY_MAP; } - SmartFMap newCopyableMap = value == null ? copyableMap.minus(key) : copyableMap.plus(key, value); - SmartFMap newMap = newCopyableMap.isEmpty() ? map.minus(COPYABLE_USER_MAP_KEY) : map.plus(COPYABLE_USER_MAP_KEY, newCopyableMap); + KeyFMap newCopyableMap = value == null ? copyableMap.minus(key) : copyableMap.plus(key, value); + KeyFMap newMap = newCopyableMap.isEmpty() ? map.minus(COPYABLE_USER_MAP_KEY) : map.plus(COPYABLE_USER_MAP_KEY, newCopyableMap); if (newMap == map || updater.compareAndSet(this, map, newMap)) { return; } } } + @Override public boolean replace(@NotNull Key key, @Nullable T oldValue, @Nullable T newValue) { while (true) { - SmartFMap map = myUserMap; + KeyFMap map = myUserMap; if (map.get(key) != oldValue) { return false; } - SmartFMap newMap = newValue == null ? map.minus(key) : map.plus(key, newValue); + KeyFMap newMap = newValue == null ? map.minus(key) : map.plus(key, newValue); if (newMap == map || updater.compareAndSet(this, map, newMap)) { return true; } } } + @Override @NotNull public T putUserDataIfAbsent(@NotNull final Key key, @NotNull final T value) { while (true) { - SmartFMap map = myUserMap; - @SuppressWarnings("unchecked") T oldValue = (T)map.get(key); + KeyFMap map = myUserMap; + T oldValue = map.get(key); if (oldValue != null) { return oldValue; } - SmartFMap newMap = map.plus(key, value); + KeyFMap newMap = map.plus(key, value); if (newMap == map || updater.compareAndSet(this, map, newMap)) { return value; } @@ -125,8 +127,12 @@ public class UserDataHolderBase implements UserDataHolderEx, Cloneable { } protected void clearUserData() { - myUserMap = SmartFMap.emptyMap(); + myUserMap = KeyFMap.EMPTY_MAP; } - private static final AtomicFieldUpdater updater = AtomicFieldUpdater.forFieldOfType(UserDataHolderBase.class, SmartFMap.class); + public boolean isUserDataEmpty() { + return myUserMap.isEmpty(); + } + + private static final AtomicFieldUpdater updater = AtomicFieldUpdater.forFieldOfType(UserDataHolderBase.class, KeyFMap.class); } diff --git a/platform/util/src/com/intellij/util/ArrayUtil.java b/platform/util/src/com/intellij/util/ArrayUtil.java index b011492ecf40..aca3963f21f3 100644 --- a/platform/util/src/com/intellij/util/ArrayUtil.java +++ b/platform/util/src/com/intellij/util/ArrayUtil.java @@ -375,6 +375,17 @@ public class ArrayUtil extends ArrayUtilRt { System.arraycopy(src, idx + 1, result, idx, length - idx - 1); return result; } + @NotNull + public static short[] remove(@NotNull final short[] src, int idx) { + int length = src.length; + if (idx < 0 || idx >= length) { + throw new IllegalArgumentException("invalid index: " + idx); + } + short[] result = new short[src.length - 1]; + System.arraycopy(src, 0, result, 0, idx); + System.arraycopy(src, idx + 1, result, idx, length - idx - 1); + return result; + } /** * @param src source array. @@ -650,6 +661,13 @@ public class ArrayUtil extends ArrayUtilRt { return -1; } + public static int indexOf(@NotNull short[] ints, short value) { + for (int i = 0; i < ints.length; i++) { + if (ints[i] == value) return i; + } + + return -1; + } public static boolean contains(final Object o, final Object... objects) { return indexOf(objects, o) >= 0; diff --git a/platform/util/src/com/intellij/util/containers/WeakValueHashMap.java b/platform/util/src/com/intellij/util/containers/WeakValueHashMap.java index c5b1e4fdbc42..1591e509a2dd 100644 --- a/platform/util/src/com/intellij/util/containers/WeakValueHashMap.java +++ b/platform/util/src/com/intellij/util/containers/WeakValueHashMap.java @@ -17,6 +17,7 @@ package com.intellij.util.containers; import gnu.trove.THashMap; import gnu.trove.TObjectHashingStrategy; +import org.jetbrains.annotations.NotNull; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; @@ -27,9 +28,9 @@ public final class WeakValueHashMap implements Map{ private final ReferenceQueue myQueue = new ReferenceQueue(); private static class MyReference extends WeakReference { - final K key; + private final K key; - public MyReference(K key, T referent, ReferenceQueue q) { + private MyReference(K key, T referent, ReferenceQueue q) { super(referent, q); this.key = key; } @@ -39,7 +40,7 @@ public final class WeakValueHashMap implements Map{ myMap = new THashMap>(); } - public WeakValueHashMap(TObjectHashingStrategy strategy) { + public WeakValueHashMap(@NotNull TObjectHashingStrategy strategy) { myMap = new THashMap>(strategy); } @@ -49,58 +50,71 @@ public final class WeakValueHashMap implements Map{ if (ref == null) { return; } - if (myMap.get(ref.key) == ref){ - myMap.remove(ref.key); + @SuppressWarnings("unchecked") + K key = (K)ref.key; + if (myMap.get(key) == ref){ + myMap.remove(key); } } } + @Override public V get(Object key) { MyReference ref = myMap.get(key); if (ref == null) return null; return ref.get(); } + @Override public V put(K key, V value) { processQueue(); MyReference oldRef = myMap.put(key, new MyReference(key, value, myQueue)); return oldRef != null ? oldRef.get() : null; } + @Override public V remove(Object key) { processQueue(); MyReference ref = myMap.remove(key); return ref != null ? ref.get() : null; } + @Override public void putAll(Map t) { throw new RuntimeException("method not implemented"); } + @Override public void clear() { myMap.clear(); } + @Override public int size() { return myMap.size(); //? } + @Override public boolean isEmpty() { return myMap.isEmpty(); //? } + @Override public boolean containsKey(Object key) { return get(key) != null; } + @Override public boolean containsValue(Object value) { throw new RuntimeException("method not implemented"); } + @Override public Set keySet() { return myMap.keySet(); } + @Override public Collection values() { List result = new ArrayList(); final Collection> refs = myMap.values(); @@ -113,6 +127,7 @@ public final class WeakValueHashMap implements Map{ return result; } + @Override public Set> entrySet() { throw new RuntimeException("method not implemented"); } diff --git a/platform/util/src/com/intellij/util/containers/WeakValueIntObjectHashMap.java b/platform/util/src/com/intellij/util/containers/WeakValueIntObjectHashMap.java new file mode 100644 index 000000000000..e58460a92faf --- /dev/null +++ b/platform/util/src/com/intellij/util/containers/WeakValueIntObjectHashMap.java @@ -0,0 +1,107 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.util.containers; + +import gnu.trove.TIntObjectHashMap; +import org.jetbrains.annotations.NotNull; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class WeakValueIntObjectHashMap { + private final TIntObjectHashMap> myMap = new TIntObjectHashMap>(); + private final ReferenceQueue myQueue = new ReferenceQueue(); + + private static class MyReference extends WeakReference { + private final int key; + String name; + + private MyReference(int key, T referent, ReferenceQueue q) { + super(referent, q); + this.key = key; + } + } + + private void processQueue() { + while(true){ + MyReference ref = (MyReference)myQueue.poll(); + if (ref == null) { + return; + } + int key = ref.key; + myMap.remove(key); + keyExpired(key); + } + } + + protected void keyExpired(int key) { + + } + + public final V get(int key) { + MyReference ref = myMap.get(key); + if (ref == null) return null; + return ref.get(); + } + + public final V put(int key, @NotNull V value) { + processQueue(); + MyReference ref = new MyReference(key, value, myQueue); + ref.name = value.toString(); + MyReference oldRef = myMap.put(key, ref); + return oldRef != null ? oldRef.get() : null; + } + + public final V remove(int key) { + processQueue(); + MyReference ref = myMap.remove(key); + return ref != null ? ref.get() : null; + } + + public final void clear() { + myMap.clear(); + processQueue(); + } + + public final int size() { + return myMap.size(); + } + + public final boolean isEmpty() { + return myMap.isEmpty(); + } + + public final boolean containsKey(int key) { + return get(key) != null; + } + + @NotNull + public final Collection values() { + List result = new ArrayList(); + Object[] refs = myMap.getValues(); + for (Object o : refs) { + @SuppressWarnings("unchecked") + final V value = ((MyReference)o).get(); + if (value != null) { + result.add(value); + } + } + return result; + } +} diff --git a/platform/util/src/com/intellij/util/keyFMap/ArrayBackedFMap.java b/platform/util/src/com/intellij/util/keyFMap/ArrayBackedFMap.java new file mode 100644 index 000000000000..0f408fa8dd8a --- /dev/null +++ b/platform/util/src/com/intellij/util/keyFMap/ArrayBackedFMap.java @@ -0,0 +1,132 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.util.keyFMap; + +import com.intellij.openapi.util.Key; +import org.jetbrains.annotations.NotNull; + +class ArrayBackedFMap implements KeyFMap { + static final int ARRAY_THRESHOLD = 8; + private final int[] keys; + private final Object[] values; + + ArrayBackedFMap(@NotNull int[] keys, @NotNull Object[] values) { + this.keys = keys; + this.values = values; + } + + @NotNull + @Override + public KeyFMap plus(@NotNull Key key, @NotNull V value) { + int oldSize = size(); + int keyCode = key.hashCode(); + int[] newKeys = null; + Object[] newValues = null; + int i; + for (i = 0; i < oldSize; i++) { + int oldKey = keys[i]; + if (keyCode == oldKey) { + if (value == values[i]) return this; + newKeys = new int[oldSize]; + newValues = new Object[oldSize]; + System.arraycopy(keys, 0, newKeys, 0, oldSize); + System.arraycopy(values, 0, newValues, 0, oldSize); + newValues[i] = value; + break; + } + } + if (i == oldSize) { + if (oldSize == ARRAY_THRESHOLD) { + return new MapBackedFMap(keys, keyCode, values, value); + } + int newSize = oldSize + 1; + newKeys = new int[newSize]; + newValues = new Object[newSize]; + System.arraycopy(keys, 0, newKeys, 0, oldSize); + System.arraycopy(values, 0, newValues, 0, oldSize); + newKeys[oldSize] = keyCode; + newValues[oldSize] = value; + } + return new ArrayBackedFMap(newKeys, newValues); + } + + private int size() { + return keys.length; + } + + @NotNull + @Override + public KeyFMap minus(@NotNull Key key) { + int oldSize = size(); + int keyCode = key.hashCode(); + for (int i = 0; i< oldSize; i++) { + int oldKey = keys[i]; + if (keyCode == oldKey) { + if (oldSize == 3) { + int i1 = (2-i)/2; + int i2 = 3 - (i+2)/2; + return new PairElementsFMap(keys[i1], values[i1], keys[i2], values[i2]); + } + int newSize = oldSize - 1; + int[] newKeys = new int[newSize]; + Object[] newValues = new Object[newSize]; + System.arraycopy(keys, 0, newKeys, 0, i); + System.arraycopy(values, 0, newValues, 0, i); + System.arraycopy(keys, i+1, newKeys, i, oldSize-i-1); + System.arraycopy(values, i+1, newValues, i, oldSize-i-1); + return new ArrayBackedFMap(newKeys, newValues); + } + } + return this; + //if (i == oldSize) { + //newKeys = new int[oldSize]; + //newValues = new Object[oldSize]; + //System.arraycopy(keys, 0, newKeys, 0, oldSize); + //System.arraycopy(values, 0, newValues, 0, oldSize); + //} + + } + + @Override + public V get(@NotNull Key key) { + int oldSize = size(); + int keyCode = key.hashCode(); + for (int i = 0; i < oldSize; i++) { + int oldKey = keys[i]; + if (keyCode == oldKey) { + //noinspection unchecked + return (V)values[i]; + } + } + return null; + } + + @Override + public String toString() { + String s = ""; + for (int i = 0; i < keys.length; i++) { + int key = keys[i]; + Object value = values[i]; + s += (s.isEmpty() ? "" : ", ") + Key.getKeyByIndex(key) + " -> " + value; + } + return "(" + s + ")"; + } + + @Override + public boolean isEmpty() { + return false; + } +} diff --git a/platform/util/src/com/intellij/util/keyFMap/EmptyFMap.java b/platform/util/src/com/intellij/util/keyFMap/EmptyFMap.java new file mode 100644 index 000000000000..d682bcb4dd46 --- /dev/null +++ b/platform/util/src/com/intellij/util/keyFMap/EmptyFMap.java @@ -0,0 +1,51 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.util.keyFMap; + +import com.intellij.openapi.util.Key; +import org.jetbrains.annotations.NotNull; + +class EmptyFMap implements KeyFMap { + EmptyFMap() { + } + + @NotNull + @Override + public KeyFMap plus(@NotNull Key key, @NotNull V value) { + return new OneElementFMap(key.hashCode(), value); + } + + @NotNull + @Override + public KeyFMap minus(@NotNull Key key) { + return this; + } + + @Override + public V get(@NotNull Key key) { + return null; + } + + @Override + public String toString() { + return ""; + } + + @Override + public boolean isEmpty() { + return true; + } +} diff --git a/platform/util/src/com/intellij/util/keyFMap/KeyFMap.java b/platform/util/src/com/intellij/util/keyFMap/KeyFMap.java new file mode 100644 index 000000000000..8c32384c1992 --- /dev/null +++ b/platform/util/src/com/intellij/util/keyFMap/KeyFMap.java @@ -0,0 +1,42 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.util.keyFMap; + +import com.intellij.openapi.util.Key; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * An immutable map optimized for storing few {@link Key} entries with relatively rare updates + * To construct a map, start with {@link KeyFMap#EMPTY_MAP} and call {@link #plus} and {@link #minus} + * + * @author peter + */ +public interface KeyFMap { + KeyFMap EMPTY_MAP = new EmptyFMap(); + + @NotNull + KeyFMap plus(@NotNull Key key, @NotNull V value); + @NotNull + KeyFMap minus(@NotNull Key key); + + @Nullable + V get(@NotNull Key key); + + String toString(); + + boolean isEmpty(); +} diff --git a/platform/util/src/com/intellij/util/keyFMap/MapBackedFMap.java b/platform/util/src/com/intellij/util/keyFMap/MapBackedFMap.java new file mode 100644 index 000000000000..1622132f0118 --- /dev/null +++ b/platform/util/src/com/intellij/util/keyFMap/MapBackedFMap.java @@ -0,0 +1,100 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.util.keyFMap; + +import com.intellij.openapi.util.Key; +import com.intellij.util.ArrayUtil; +import gnu.trove.TIntObjectHashMap; +import gnu.trove.TIntObjectProcedure; +import org.jetbrains.annotations.NotNull; + +class MapBackedFMap extends TIntObjectHashMap implements KeyFMap { + private MapBackedFMap(@NotNull MapBackedFMap oldMap, final int exclude) { + super(oldMap.size()); + oldMap.forEachEntry(new TIntObjectProcedure() { + @Override + public boolean execute(int key, Object val) { + if (key != exclude) put(key, val); + assert key >= 0 : key; + return true; + } + }); + assert size() > ArrayBackedFMap.ARRAY_THRESHOLD; + } + + MapBackedFMap(@NotNull int[] keys, int newKey, @NotNull Object[] values, @NotNull Object newValue) { + for (int i = 0; i < keys.length; i++) { + int key = keys[i]; + Object value = values[i]; + put(key, value); + assert key >= 0 : key; + } + put(newKey, newValue); + assert newKey >= 0 : newKey; + assert size() > ArrayBackedFMap.ARRAY_THRESHOLD; + } + + @NotNull + @Override + public KeyFMap plus(@NotNull Key key, @NotNull V value) { + int keyCode = key.hashCode(); + assert keyCode >= 0 : key; + @SuppressWarnings("unchecked") + V oldValue = (V)get(keyCode); + if (value == oldValue) return this; + MapBackedFMap newMap = new MapBackedFMap(this, -1); + newMap.put(keyCode, value); + return newMap; + } + + @NotNull + @Override + public KeyFMap minus(@NotNull Key key) { + int oldSize = size(); + int keyCode = key.hashCode(); + if (!containsKey(keyCode)) { + return this; + } + if (oldSize == ArrayBackedFMap.ARRAY_THRESHOLD + 1) { + int[] keys = keys(); + Object[] values = getValues(); + int i = ArrayUtil.indexOf(keys, keyCode); + keys = ArrayUtil.remove(keys, i); + values = ArrayUtil.remove(values, i); + return new ArrayBackedFMap(keys, values); + } + return new MapBackedFMap(this, keyCode); + } + + @Override + public V get(@NotNull Key key) { + //noinspection unchecked + return (V)get(key.hashCode()); + } + + @Override + public String toString() { + final StringBuilder s = new StringBuilder(); + forEachEntry(new TIntObjectProcedure() { + @Override + public boolean execute(int key, Object value) { + s.append(s.length() == 0 ? "" : ", ").append(Key.getKeyByIndex(key)).append(" -> ").append(value); + return true; + } + }); + return "[" + s.toString() + "]"; + } +} diff --git a/platform/util/src/com/intellij/util/keyFMap/OneElementFMap.java b/platform/util/src/com/intellij/util/keyFMap/OneElementFMap.java new file mode 100644 index 000000000000..76488c68c979 --- /dev/null +++ b/platform/util/src/com/intellij/util/keyFMap/OneElementFMap.java @@ -0,0 +1,62 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.util.keyFMap; + +import com.intellij.openapi.util.Key; +import org.jetbrains.annotations.NotNull; + +class OneElementFMap implements KeyFMap { + private final int myKeyCode; + private final V myValue; + + OneElementFMap(int keyCode, @NotNull V value) { + myKeyCode = keyCode; + myValue = value; + } + + @NotNull + @Override + public KeyFMap plus(@NotNull Key key, @NotNull V value) { + int keyCode = key.hashCode(); + if (myKeyCode == keyCode) return new OneElementFMap(keyCode, value); + return new PairElementsFMap(myKeyCode, myValue, keyCode, value); + } + + @NotNull + @Override + public KeyFMap minus(@NotNull Key key) { + if (key.hashCode() == myKeyCode) { + return KeyFMap.EMPTY_MAP; + } + return this; + } + + @Override + public V get(@NotNull Key key) { + //noinspection unchecked + return myKeyCode == key.hashCode() ? (V)myValue : null; + } + + @Override + public String toString() { + return "<"+Key.getKeyByIndex(myKeyCode) + " -> " + myValue+">"; + } + + @Override + public boolean isEmpty() { + return false; + } +} diff --git a/platform/util/src/com/intellij/util/keyFMap/PairElementsFMap.java b/platform/util/src/com/intellij/util/keyFMap/PairElementsFMap.java new file mode 100644 index 000000000000..35ea8b957e36 --- /dev/null +++ b/platform/util/src/com/intellij/util/keyFMap/PairElementsFMap.java @@ -0,0 +1,69 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.util.keyFMap; + +import com.intellij.openapi.util.Key; +import org.jetbrains.annotations.NotNull; + +class PairElementsFMap implements KeyFMap { + private final int key1; + private final int key2; + private final Object value1; + private final Object value2; + + PairElementsFMap(int key1, @NotNull Object value1, int key2, @NotNull Object value2) { + this.key1 = key1; + this.value1 = value1; + this.key2 = key2; + this.value2 = value2; + assert key1 != key2; + } + + @NotNull + @Override + public KeyFMap plus(@NotNull Key key, @NotNull V value) { + int keyCode = key.hashCode(); + if (keyCode == key1) return new PairElementsFMap(keyCode, value, key2, value2); + if (keyCode == key2) return new PairElementsFMap(keyCode, value, key1, value1); + return new ArrayBackedFMap(new int[]{key1, key2, keyCode}, new Object[]{value1, value2, value}); + } + + @NotNull + @Override + public KeyFMap minus(@NotNull Key key) { + int keyCode = key.hashCode(); + if (keyCode == key1) return new OneElementFMap(key2, value2); + if (keyCode == key2) return new OneElementFMap(key1, value1); + return this; + } + + @Override + public V get(@NotNull Key key) { + int keyCode = key.hashCode(); + //noinspection unchecked + return keyCode == key1 ? (V)value1 : keyCode == key2 ? (V)value2 : null; + } + + @Override + public String toString() { + return "Pair: ("+ Key.getKeyByIndex(key1) + " -> " + value1+"; "+Key.getKeyByIndex(key2) + " -> " + value2 + ")"; + } + + @Override + public boolean isEmpty() { + return false; + } +} diff --git a/platform/util/src/com/intellij/util/keyFMap/ShortObjectHashMap.java b/platform/util/src/com/intellij/util/keyFMap/ShortObjectHashMap.java new file mode 100644 index 000000000000..4bd812fb0622 --- /dev/null +++ b/platform/util/src/com/intellij/util/keyFMap/ShortObjectHashMap.java @@ -0,0 +1,317 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.util.keyFMap; + +import gnu.trove.TIntObjectProcedure; +import gnu.trove.TPrimitiveHash; +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; + +public class ShortObjectHashMap extends TPrimitiveHash { + private V[] _values; + private short[] _set; + + + /** + * Creates a new TIntObjectHashMap instance with the default + * capacity and load factor. + */ + public ShortObjectHashMap() { + super(); + } + + /** + * Creates a new TIntObjectHashMap instance with a prime + * capacity equal to or greater than initialCapacity and + * with the default load factor. + * + * @param initialCapacity an int value + */ + public ShortObjectHashMap(int initialCapacity) { + super(initialCapacity); + } + + /** + * initializes the hashtable to a prime capacity which is at least + * initialCapacity + 1. + * + * @param initialCapacity an int value + * @return the actual capacity chosen + */ + @Override + protected int setUp(int initialCapacity) { + + int capacity = super.setUp(initialCapacity); + //noinspection unchecked + _values = (V[])new Object[capacity]; + _set = new short[capacity]; + return capacity; + } + + /** + * Inserts a key/value pair into the map. + * + * @param key an int value + * @param value an Object value + * @return the previous value associated with key, + * or null if none was found. + */ + public V put(short key, @NotNull V value) { + V previous = null; + int index = insertionIndex(key); + boolean isNewMapping = true; + if (index < 0) { + index = -index - 1; + previous = _values[index]; + isNewMapping = false; + } + byte previousState = _states[index]; + _set[index] = key; + _states[index] = FULL; + _values[index] = value; + if (isNewMapping) { + postInsertHook(previousState == FREE); + } + + return previous; + } + + /** + * rehashes the map to the new capacity. + * + * @param newCapacity an int value + */ + @Override + protected void rehash(int newCapacity) { + int oldCapacity = _set.length; + short[] oldKeys = _set; + V[] oldVals = _values; + byte[] oldStates = _states; + + _set = new short[newCapacity]; + //noinspection unchecked + _values = (V[])new Object[newCapacity]; + _states = new byte[newCapacity]; + + for (int i = oldCapacity; i-- > 0; ) { + if (oldStates[i] == FULL) { + short o = oldKeys[i]; + int index = insertionIndex(o); + _set[index] = o; + _values[index] = oldVals[i]; + _states[index] = FULL; + } + } + } + + /** + * retrieves the value for key + * + * @param key an int value + * @return the value of key or null if no such mapping exists. + */ + public V get(short key) { + int index = index(key); + return index < 0 ? null : _values[index]; + } + + /** + * Empties the map. + */ + @Override + public void clear() { + super.clear(); + + Arrays.fill(_set, (short)0); + Arrays.fill(_values, null); + Arrays.fill(_states, FREE); + } + + /** + * Deletes a key/value pair from the map. + * + * @param key an int value + * @return an Object value + */ + public V remove(short key) { + V prev = null; + int index = index(key); + if (index >= 0) { + prev = _values[index]; + removeAt(index); // clear key,state; adjust size + } + return prev; + } + + + /** + * removes the mapping at index from the map. + * + * @param index an int value + */ + @Override + protected void removeAt(int index) { + _values[index] = null; + _set[index] = 0; + super.removeAt(index); // clear key, state; adjust size + } + + /** + * Returns the values of the map. + * + * @return a Collection value + */ + public Object[] getValues() { + Object[] vals = new Object[size()]; + V[] v = _values; + byte[] states = _states; + + for (int i = v.length, j = 0; i-- > 0; ) { + if (states[i] == FULL) { + vals[j++] = v[i]; + } + } + return vals; + } + + /** + * returns the keys of the map. + * + * @return a Set value + */ + public short[] keys() { + short[] keys = new short[size()]; + short[] k = _set; + byte[] states = _states; + + for (int i = k.length, j = 0; i-- > 0; ) { + if (states[i] == FULL) { + keys[j++] = k[i]; + } + } + return keys; + } + + + /** + * checks for the present of key in the keys of the map. + * + * @param key an int value + * @return a boolean value + */ + public boolean containsKey(int key) { + return index(key) >= 0; + } + + + /** + * Locates the index of val. + * + * @param val an int value + * @return the index of val or -1 if it isn't in the set. + */ + protected int index(int val) { + byte[] states = _states; + short[] set = _set; + int length = states.length; + int hash = val & 0x7fffffff; + int index = hash % length; + + if (states[index] != FREE && + (states[index] == REMOVED || set[index] != val)) { + // see Knuth, p. 529 + int probe = 1 + hash % (length - 2); + + do { + index -= probe; + if (index < 0) { + index += length; + } + } + while (states[index] != FREE && + (states[index] == REMOVED || set[index] != val)); + } + + return states[index] == FREE ? -1 : index; + } + + /** + * Locates the index at which val can be inserted. if + * there is already a value equal()ing val in the set, + * returns that value as a negative integer. + * + * @param val an int value + * @return an int value + */ + protected int insertionIndex(int val) { + + byte[] states = _states; + short[] set = _set; + int length = states.length; + int hash = val & 0x7fffffff; + int index = hash % length; + + if (states[index] == FREE) { + return index; // empty, all done + } + else if (states[index] == FULL && set[index] == val) { + return -index - 1; // already stored + } + else { // already FULL or REMOVED, must probe + // compute the double hash + int probe = 1 + hash % (length - 2); + // starting at the natural offset, probe until we find an + // offset that isn't full. + do { + index -= probe; + if (index < 0) { + index += length; + } + } + while (states[index] == FULL && set[index] != val); + + // if the index we found was removed: continue probing until we + // locate a free location or an element which equal()s the + // one we have. + if (states[index] == REMOVED) { + int firstRemoved = index; + while (states[index] != FREE && + (states[index] == REMOVED || set[index] != val)) { + index -= probe; + if (index < 0) { + index += length; + } + } + return states[index] == FULL ? -index - 1 : firstRemoved; + } + // if it's full, the key is already stored + return states[index] == FULL ? -index - 1 : index; + } + } + + public boolean forEachEntry(TIntObjectProcedure procedure) { + byte[] states = _states; + short[] keys = _set; + V[] values = _values; + for (int i = keys.length; i-- > 0; ) { + if (states[i] == FULL && !procedure.execute(keys[i], values[i])) { + return false; + } + } + return true; + } +} // TIntObjectHashMap diff --git a/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/formove/FilePathComparator.java b/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/formove/FilePathComparator.java index bda6f4c92805..090f88a3fe72 100644 --- a/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/formove/FilePathComparator.java +++ b/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/formove/FilePathComparator.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.diff.impl.patch.formove; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VirtualFile; import java.util.Comparator; @@ -27,7 +28,7 @@ public final class FilePathComparator implements Comparator { } public int compare(final VirtualFile o1, final VirtualFile o2) { - if (o1 == o2) return 0; + if (Comparing.equal(o1, o2)) return 0; return o1.getPath().compareTo(o2.getPath()); } } diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java index 2378efaec35f..2ab5790586fb 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java @@ -269,7 +269,7 @@ public abstract class VcsVFSListener implements Disposable { final String newPath = newParentPath + "/" + newName; boolean foundExistingInfo = false; for (MovedFileInfo info : myMovedFiles) { - if (info.myFile == file) { + if (Comparing.equal(info.myFile, file)) { info.myNewPath = newPath; foundExistingInfo = true; break; diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/IgnoredFileBean.java b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/IgnoredFileBean.java index b59fa802abf5..0ed4bc41c12c 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/IgnoredFileBean.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/IgnoredFileBean.java @@ -23,6 +23,7 @@ package com.intellij.openapi.vcs.changes; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; @@ -105,15 +106,15 @@ public class IgnoredFileBean { } else { VirtualFile selector = resolve(); - if (selector == NullVirtualFile.INSTANCE) return false; + if (Comparing.equal(selector, NullVirtualFile.INSTANCE)) return false; if (myType == IgnoreSettingsType.FILE) { - return selector == file; + return Comparing.equal(selector, file); } else { if ("./".equals(myPath)) { // special case for ignoring the project base dir (IDEADEV-16056) - return !file.isDirectory() && file.getParent() == selector; + return !file.isDirectory() && Comparing.equal(file.getParent(), selector); } return VfsUtil.isAncestor(selector, file, false); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/FilePathImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/FilePathImpl.java index ab38f7f6e305..24d0966c22ab 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/FilePathImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/FilePathImpl.java @@ -19,6 +19,8 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.FileTypeRegistry; +import com.intellij.openapi.fileTypes.UnknownFileType; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.io.FileUtil; @@ -42,9 +44,14 @@ public class FilePathImpl implements FilePath { private final String myName; @NotNull private final File myFile; private boolean myIsDirectory; - private boolean myNonLocal; + private final boolean myLocal; - private FilePathImpl(VirtualFile virtualParent, String name, final boolean isDirectory, VirtualFile child, final boolean forDeleted) { + private FilePathImpl(VirtualFile virtualParent, + @NotNull String name, + final boolean isDirectory, + VirtualFile child, + final boolean forDeleted) { + myLocal = true; myVirtualParent = virtualParent; myName = name; myIsDirectory = isDirectory; @@ -55,7 +62,7 @@ public class FilePathImpl implements FilePath { myFile = new File(new File(myVirtualParent.getPath()), myName); } - if (! forDeleted) { + if (!forDeleted) { if (child == null) { refresh(); } @@ -65,6 +72,15 @@ public class FilePathImpl implements FilePath { } } + private void detectCharset() { + VirtualFile file = myVirtualFile; + if (file == null || !file.isValid() || file.isDirectory()) return; + FileType fileType = file.getFileType(); + if (fileType == UnknownFileType.INSTANCE) { + FileTypeRegistry.getInstance().detectFileTypeFromContent(file); + } + } + @Heavy public FilePathImpl(VirtualFile virtualParent, String name, final boolean isDirectory) { this(virtualParent, name, isDirectory, null, false); @@ -75,10 +91,14 @@ public class FilePathImpl implements FilePath { this(virtualParent, name, isDirectory, null, forDeleted); } - public FilePathImpl(final File file, final boolean isDirectory) { + public FilePathImpl(@NotNull File file, final boolean isDirectory) { + this(file, isDirectory, true); + } + private FilePathImpl(@NotNull File file, final boolean isDirectory, boolean local) { myFile = file; myName = file.getName(); myIsDirectory = isDirectory; + myLocal = local; } public FilePathImpl(@NotNull VirtualFile virtualFile) { @@ -90,7 +110,8 @@ public class FilePathImpl implements FilePath { if (getVirtualFile() != null && subPath.indexOf('/') == -1 && subPath.indexOf('\\') == -1) { return new FilePathImpl(getVirtualFile(), subPath, isDirectory, true); - } else { + } + else { return new FilePathImpl(new File(getIOFile(), subPath), isDirectory); } } @@ -105,17 +126,18 @@ public class FilePathImpl implements FilePath { } else { if (! isSpecialName(myName) && ! isSpecialName(((FilePath)o).getName()) && - (! Comparing.equal(myName, ((FilePath)o).getName()))) return false; + ! Comparing.equal(myName, ((FilePath)o).getName())) return false; return myFile.equals(((FilePath)o).getIOFile()); } } - private boolean isSpecialName(final String name) { + private static boolean isSpecialName(final String name) { return ".".equals(name) || "..".equals(name); } + @Override public void refresh() { - if (!myNonLocal) { + if (myLocal) { if (myVirtualParent == null) { myVirtualFile = LocalFileSystem.getInstance().findFileByIoFile(myFile); } @@ -125,12 +147,14 @@ public class FilePathImpl implements FilePath { } } + @Override public void hardRefresh() { - if (! myNonLocal && (myVirtualFile == null || ! myVirtualFile.isValid())) { + if (myLocal && (myVirtualFile == null || ! myVirtualFile.isValid())) { myVirtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(myFile); } } + @Override public String getPath() { final VirtualFile virtualFile = myVirtualFile; if (virtualFile != null && virtualFile.isValid()) { @@ -145,6 +169,7 @@ public class FilePathImpl implements FilePath { myIsDirectory = isDirectory; } + @Override public boolean isDirectory() { if (myVirtualFile == null) { return myIsDirectory; @@ -154,6 +179,7 @@ public class FilePathImpl implements FilePath { } } + @Override public boolean isUnder(FilePath parent, boolean strict) { if (myVirtualFile != null && parent.getVirtualFile() != null) { return VfsUtil.isAncestor(parent.getVirtualFile(), myVirtualFile, strict); @@ -161,6 +187,7 @@ public class FilePathImpl implements FilePath { return FileUtil.isAncestor(parent.getIOFile(), getIOFile(), strict); } + @Override public FilePath getParentPath() { if (myVirtualParent != null && myVirtualParent.isValid()) { return new FilePathImpl(myVirtualParent); @@ -177,14 +204,17 @@ public class FilePathImpl implements FilePath { return new FilePathImpl(new File(path.substring(0, pos)), true); } + @Override @Nullable public VirtualFile getVirtualFile() { if (myVirtualFile != null && !myVirtualFile.isValid()) { myVirtualFile = null; } + detectCharset(); return myVirtualFile; } + @Override @Nullable public VirtualFile getVirtualFileParent() { if (myVirtualParent != null && !myVirtualParent.isValid()) { @@ -193,15 +223,18 @@ public class FilePathImpl implements FilePath { return myVirtualParent; } + @Override @NotNull public File getIOFile() { return myFile; } + @Override public String getName() { return myName; } + @Override public String getPresentableUrl() { if (myVirtualFile == null) { return myFile.getAbsolutePath(); @@ -211,18 +244,21 @@ public class FilePathImpl implements FilePath { } } + @Override @Nullable public Document getDocument() { - if ((myVirtualFile == null) || (myVirtualFile.getFileType().isBinary())) { + if (myVirtualFile == null || myVirtualFile.getFileType().isBinary()) { return null; } return FileDocumentManager.getInstance().getDocument(myVirtualFile); } + @Override public Charset getCharset() { return getCharset(null); } + @Override public Charset getCharset(Project project) { // try to find existing virtual file VirtualFile existing = myVirtualFile != null && myVirtualFile.isValid() ? myVirtualFile : null; @@ -248,6 +284,7 @@ public class FilePathImpl implements FilePath { return e.getDefaultCharset(); } + @Override public FileType getFileType() { return myVirtualFile != null ? myVirtualFile.getFileType() : FileTypeManager.getInstance().getFileTypeByFileName(myFile.getName()); } @@ -335,9 +372,7 @@ public class FilePathImpl implements FilePath { if (file == null) { file = new File(path); } - FilePathImpl result = new FilePathImpl(file, directory); - result.myNonLocal = true; - return result; + return new FilePathImpl(file, directory, false); } @Override @@ -346,7 +381,8 @@ public class FilePathImpl implements FilePath { return "FilePath[" + myFile + "]"; } + @Override public boolean isNonLocal() { - return myNonLocal; + return !myLocal; } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/annotate/VFSForAnnotationListener.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/annotate/VFSForAnnotationListener.java index 2dd1f6faefcc..5032b8f8cde6 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/annotate/VFSForAnnotationListener.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/annotate/VFSForAnnotationListener.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.vcs.annotate; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileAdapter; import com.intellij.openapi.vfs.VirtualFileEvent; @@ -32,7 +33,7 @@ public class VFSForAnnotationListener extends VirtualFileAdapter { } public void propertyChanged(VirtualFilePropertyEvent event) { - if (myFile != event.getFile()) return; + if (!Comparing.equal(myFile, event.getFile())) return; if (! event.isFromRefresh()) return; if (event.getPropertyName().equals(VirtualFile.PROP_WRITABLE)) { @@ -43,7 +44,7 @@ public class VFSForAnnotationListener extends VirtualFileAdapter { } public void contentsChanged(VirtualFileEvent event) { - if (myFile != event.getFile()) return; + if (!Comparing.equal(myFile, event.getFile())) return; if (! event.isFromRefresh()) return; if (! myFile.isWritable()) { fireAnnotationChanged(); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeImpl.java index fcdd21c64d16..210fda396d50 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeImpl.java @@ -18,6 +18,7 @@ package com.intellij.openapi.vcs.changes; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.vcs.*; import com.intellij.openapi.vfs.VfsUtil; @@ -224,7 +225,7 @@ public class VcsDirtyScopeImpl extends VcsModifiableDirtyScope { if (newcomer.isDirectory()) { final List files = new ArrayList(myDirtyFiles); for (FilePath oldBoy : files) { - if (!oldBoy.isDirectory() && oldBoy.getVirtualFileParent() == newcomer.getVirtualFile()) { + if (!oldBoy.isDirectory() && Comparing.equal(oldBoy.getVirtualFileParent(), newcomer.getVirtualFile())) { myDirtyFiles.remove(oldBoy); } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserFileNode.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserFileNode.java index 1335e6fcb5e4..8f844dac73de 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserFileNode.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserFileNode.java @@ -23,6 +23,7 @@ import com.intellij.openapi.vcs.changes.ChangeListManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.SimpleTextAttributes; import com.intellij.util.PlatformIcons; +import org.jetbrains.annotations.NotNull; /** * @author yole @@ -30,19 +31,20 @@ import com.intellij.util.PlatformIcons; public class ChangesBrowserFileNode extends ChangesBrowserNode { private final Project myProject; - public ChangesBrowserFileNode(Project project, VirtualFile userObject) { + public ChangesBrowserFileNode(Project project, @NotNull VirtualFile userObject) { super(userObject); myProject = project; - if (!userObject.isDirectory()) { - myCount = 1; - } else { + if (userObject.isDirectory()) { myDirectoryCount = 1; } + else { + myCount = 1; + } } @Override protected boolean isDirectory() { - return (getUserObject()).isDirectory() && + return getUserObject().isDirectory() && FileStatusManager.getInstance(myProject).getStatus(getUserObject()) != FileStatus.NOT_CHANGED; } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserNode.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserNode.java index 8406bd08b0e9..9cc98f10ad79 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserNode.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserNode.java @@ -108,6 +108,7 @@ public class ChangesBrowserNode extends DefaultMutableTreeNode { return new ChangesBrowserNode(userObject); } + @Override public void insert(MutableTreeNode newChild, int childIndex) { super.insert(newChild, childIndex); myCount = -1; @@ -233,6 +234,7 @@ public class ChangesBrowserNode extends DefaultMutableTreeNode { return userObject == null ? "" : userObject.toString(); } + @Override public T getUserObject() { //noinspection unchecked return (T) userObject; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesListView.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesListView.java index a4f9e24599fa..63a19e858ebf 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesListView.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesListView.java @@ -19,7 +19,6 @@ import com.intellij.ide.CopyProvider; import com.intellij.ide.dnd.*; import com.intellij.ide.util.treeView.TreeState; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileChooser.actions.VirtualFileDeleteProvider; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.project.Project; @@ -28,7 +27,7 @@ import com.intellij.openapi.util.Trinity; import com.intellij.openapi.vcs.*; import com.intellij.openapi.vcs.changes.*; import com.intellij.openapi.vcs.changes.issueLinks.TreeLinkMouseListener; -import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.PopupHandler; import com.intellij.ui.SmartExpander; @@ -59,8 +58,6 @@ import java.util.List; * @author max */ public class ChangesListView extends Tree implements TypeSafeDataProvider, AdvancedDnDSource { - private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.ui.ChangesListView"); - private ChangesListView.DropTarget myDropTarget; private DnDManager myDndManager; private ChangeListOwner myDragOwner; @@ -92,6 +89,7 @@ public class ChangesListView extends Tree implements TypeSafeDataProvider, Advan new TreeLinkMouseListener(new ChangesBrowserNodeRenderer(myProject, false, false)).installOn(this); } + @Override public DefaultTreeModel getModel() { return (DefaultTreeModel)super.getModel(); } @@ -105,6 +103,7 @@ public class ChangesListView extends Tree implements TypeSafeDataProvider, Advan myDndManager.registerTarget(myDropTarget, this); } + @Override public void dispose() { if (myDropTarget != null) { myDndManager.unregisterSource(this); @@ -175,6 +174,7 @@ public class ChangesListView extends Tree implements TypeSafeDataProvider, Advan } } + @Override public void calcData(DataKey key, DataSink sink) { if (key == VcsDataKeys.CHANGES) { sink.put(VcsDataKeys.CHANGES, getSelectedChanges()); @@ -233,7 +233,7 @@ public class ChangesListView extends Tree implements TypeSafeDataProvider, Advan else if (key == VcsDataKeys.CHANGES_IN_LIST_KEY) { final TreePath selectionPath = getSelectionPath(); if (selectionPath != null && selectionPath.getPathCount() > 1) { - ChangesBrowserNode firstNode = (ChangesBrowserNode)selectionPath.getPathComponent(1); + ChangesBrowserNode firstNode = (ChangesBrowserNode)selectionPath.getPathComponent(1); if (firstNode instanceof ChangesBrowserChangeListNode) { final List list = firstNode.getAllChangesUnder(); sink.put(VcsDataKeys.CHANGES_IN_LIST_KEY, list); @@ -262,7 +262,7 @@ public class ChangesListView extends Tree implements TypeSafeDataProvider, Advan if (path.getPathCount() > 1) { ChangesBrowserNode firstNode = (ChangesBrowserNode)path.getPathComponent(1); if (tag == null || firstNode.getUserObject() == tag) { - ChangesBrowserNode node = (ChangesBrowserNode)path.getLastPathComponent(); + ChangesBrowserNode node = (ChangesBrowserNode)path.getLastPathComponent(); files.addAll(node.getAllFilesUnder()); } } @@ -279,7 +279,7 @@ public class ChangesListView extends Tree implements TypeSafeDataProvider, Advan if (path.getPathCount() > 1) { ChangesBrowserNode firstNode = (ChangesBrowserNode)path.getPathComponent(1); if (tag == null || firstNode.getUserObject() == tag) { - ChangesBrowserNode node = (ChangesBrowserNode)path.getLastPathComponent(); + ChangesBrowserNode node = (ChangesBrowserNode)path.getLastPathComponent(); files.addAll(node.getAllFilePathsUnder()); } } @@ -296,7 +296,7 @@ public class ChangesListView extends Tree implements TypeSafeDataProvider, Advan if (path.getPathCount() > 1) { ChangesBrowserNode firstNode = (ChangesBrowserNode)path.getPathComponent(1); if (firstNode.getUserObject() == TreeModelBuilder.LOCALLY_DELETED_NODE) { - ChangesBrowserNode node = (ChangesBrowserNode)path.getLastPathComponent(); + ChangesBrowserNode node = (ChangesBrowserNode)path.getLastPathComponent(); final List objectsUnder = node.getAllObjectsUnder(LocallyDeletedChange.class); files.addAll(objectsUnder); } @@ -325,7 +325,7 @@ public class ChangesListView extends Tree implements TypeSafeDataProvider, Advan files.addAll(getSelectedVirtualFiles(null)); - return VfsUtil.toVirtualFileArray(files); + return VfsUtilCore.toVirtualFileArray(files); } protected boolean haveSelectedFileType(final Object tag) { @@ -395,13 +395,13 @@ public class ChangesListView extends Tree implements TypeSafeDataProvider, Advan } for (TreePath path : paths) { - ChangesBrowserNode node = (ChangesBrowserNode)path.getLastPathComponent(); + ChangesBrowserNode node = (ChangesBrowserNode)path.getLastPathComponent(); changes.addAll(node.getAllChangesUnder()); } - if (changes.size() == 0) { + if (changes.isEmpty()) { final List selectedModifiedWithoutEditing = getSelectedModifiedWithoutEditing(); - if (selectedModifiedWithoutEditing != null && selectedModifiedWithoutEditing.size() > 0) { + if (selectedModifiedWithoutEditing != null && !selectedModifiedWithoutEditing.isEmpty()) { for(VirtualFile file: selectedModifiedWithoutEditing) { AbstractVcs vcs = ProjectLevelVcsManager.getInstance(myProject).getVcsFor(file); if (vcs == null) continue; @@ -451,6 +451,7 @@ public class ChangesListView extends Tree implements TypeSafeDataProvider, Advan PopupHandler.installPopupHandler(this, myMenuGroup, ActionPlaces.CHANGES_VIEW_POPUP, ActionManager.getInstance()); } + @Override public void updateUI() { super.updateUI(); if (myMenuGroup != null) { @@ -577,6 +578,7 @@ public class ChangesListView extends Tree implements TypeSafeDataProvider, Advan } public class DropTarget implements DnDTarget { + @Override public boolean update(DnDEvent aEvent) { aEvent.hideHighlighter(); aEvent.setDropPossible(false, ""); @@ -614,6 +616,7 @@ public class ChangesListView extends Tree implements TypeSafeDataProvider, Advan return false; } + @Override public void drop(DnDEvent aEvent) { Object attached = aEvent.getAttachedObject(); if (!(attached instanceof ChangeListDragBean)) return; @@ -625,9 +628,11 @@ public class ChangesListView extends Tree implements TypeSafeDataProvider, Advan } } + @Override public void cleanUpOnLeave() { } + @Override public void updateDraggedImage(Image image, Point dropPoint, Point imageOffset) { } } @@ -645,39 +650,47 @@ public class ChangesListView extends Tree implements TypeSafeDataProvider, Advan } private static class NodeToTextConvertor implements Convertor { + @Override public String convert(final TreePath path) { ChangesBrowserNode node = (ChangesBrowserNode)path.getLastPathComponent(); return node.getTextPresentation(); } } + @Override public boolean canStartDragging(DnDAction action, Point dragOrigin) { return action == DnDAction.MOVE && - (getSelectedChanges().length > 0 || getSelectedUnversionedFiles().size() > 0 || getSelectedIgnoredFiles().size() > 0); + (getSelectedChanges().length > 0 || !getSelectedUnversionedFiles().isEmpty() || !getSelectedIgnoredFiles().isEmpty()); } + @Override public DnDDragStartBean startDragging(DnDAction action, Point dragOrigin) { return new DnDDragStartBean(new ChangeListDragBean(this, getSelectedChanges(), getSelectedUnversionedFiles(), getSelectedIgnoredFiles())); } + @Override @Nullable public Pair createDraggedImage(DnDAction action, Point dragOrigin) { final Image image = DragImageFactory.createImage(this); return new Pair(image, new Point(-image.getWidth(null), -image.getHeight(null))); } + @Override public void dragDropEnd() { } + @Override public void dropActionChanged(final int gestureModifiers) { } + @Override @NotNull public JComponent getComponent() { return this; } + @Override public void processMouseEvent(final MouseEvent e) { if (MouseEvent.MOUSE_RELEASED == e.getID() && !isSelectionEmpty() && !e.isShiftDown() && !e.isControlDown() && !e.isMetaDown() && !e.isPopupTrigger()) { @@ -694,10 +707,12 @@ public class ChangesListView extends Tree implements TypeSafeDataProvider, Advan super.processMouseEvent(e); } + @Override public boolean isOverSelection(final Point point) { return TreeUtil.isOverSelection(this, point); } + @Override public void dropSelectionButUnderPoint(final Point point) { TreeUtil.dropSelectionButUnderPoint(this, point); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/TreeModelBuilder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/TreeModelBuilder.java index 8b9cfa09f8d0..bb770fde10dc 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/TreeModelBuilder.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/TreeModelBuilder.java @@ -32,6 +32,7 @@ import com.intellij.util.containers.MultiMap; import com.intellij.util.ui.tree.TreeUtil; import com.intellij.vcsUtil.VcsUtil; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.tree.DefaultTreeModel; @@ -68,6 +69,7 @@ public class TreeModelBuilder { final ChangesGroupingPolicy policy = createGroupingPolicy(); for (final Change change : changes) { insertChangeNode(change, policy, root, new Computable() { + @Override public ChangesBrowserNode compute() { return new ChangesBrowserChangeNode(myProject, change, changeNodeDecorator); } @@ -92,7 +94,7 @@ public class TreeModelBuilder { return myPolicy; } - public DefaultTreeModel buildModelFromFiles(final List files) { + public DefaultTreeModel buildModelFromFiles(@NotNull List files) { buildVirtualFiles(files, null); collapseDirectories(model, root); sortNodes(); @@ -119,6 +121,7 @@ public class TreeModelBuilder { myReporter.report(state); } + @Override public void preDecorate(Change change, ChangesBrowserNodeRenderer renderer, boolean showFlatten) { } } @@ -129,7 +132,8 @@ public class TreeModelBuilder { final List modifiedWithoutEditing, final MultiMap switchedFiles, @Nullable Map switchedRoots, - @Nullable final List ignoredFiles, @Nullable final List lockedFolders, + @Nullable final List ignoredFiles, + @Nullable final List lockedFolders, @Nullable final Map logicallyLockedFiles) { resetGrouping(); buildModel(changeLists); @@ -139,7 +143,7 @@ public class TreeModelBuilder { buildVirtualFiles(modifiedWithoutEditing, ChangesBrowserNode.MODIFIED_WITHOUT_EDITING_TAG); } final boolean manyUnversioned = unversionedFiles.getSecond() > unversionedFiles.getFirst().size(); - if (manyUnversioned || (! unversionedFiles.getFirst().isEmpty())) { + if (manyUnversioned || ! unversionedFiles.getFirst().isEmpty()) { resetGrouping(); if (manyUnversioned) { @@ -149,7 +153,7 @@ public class TreeModelBuilder { buildVirtualFiles(unversionedFiles.getFirst(), ChangesBrowserNode.UNVERSIONED_FILES_TAG); } } - if (switchedRoots != null && (! switchedRoots.isEmpty())) { + if (switchedRoots != null && ! switchedRoots.isEmpty()) { resetGrouping(); buildSwitchedRoots(switchedRoots); } @@ -165,7 +169,7 @@ public class TreeModelBuilder { resetGrouping(); buildVirtualFiles(lockedFolders, ChangesBrowserNode.LOCKED_FOLDERS_TAG); } - if (logicallyLockedFiles != null && (! logicallyLockedFiles.isEmpty())) { + if (logicallyLockedFiles != null && ! logicallyLockedFiles.isEmpty()) { resetGrouping(); buildLogicallyLockedFiles(logicallyLockedFiles); } @@ -188,7 +192,7 @@ public class TreeModelBuilder { myPolicyInitialized = false; } - public DefaultTreeModel buildModel(List changeLists) { + public DefaultTreeModel buildModel(@NotNull List changeLists) { final RemoteRevisionsCache revisionsCache = RemoteRevisionsCache.getInstance(myProject); for (ChangeList list : changeLists) { final List changes = new ArrayList(list.getChanges()); @@ -203,6 +207,7 @@ public class TreeModelBuilder { final MyChangeNodeUnderChangeListDecorator decorator = new MyChangeNodeUnderChangeListDecorator(revisionsCache, new ChangeListRemoteState.Reporter(i, listRemoteState)); insertChangeNode(change, policy, listNode, new Computable() { + @Override public ChangesBrowserNode compute() { return new ChangesBrowserChangeNode(myProject, change, decorator); } @@ -220,12 +225,13 @@ public class TreeModelBuilder { return ourInstance; } + @Override public int compare(Change o1, Change o2) { final FilePath fp1 = ChangesUtil.getFilePath(o1); final FilePath fp2 = ChangesUtil.getFilePath(o2); final int diff = fp1.getIOFile().getPath().length() - fp2.getIOFile().getPath().length(); - return diff == 0 ? 0 : (diff < 0 ? -1 : 1); + return diff == 0 ? 0 : diff < 0 ? -1 : 1; } } @@ -238,7 +244,7 @@ public class TreeModelBuilder { } } */ - private void buildVirtualFiles(final List files, @Nullable final Object tag) { + private void buildVirtualFiles(@NotNull List files, @Nullable final Object tag) { final ChangesBrowserNode baseNode = createNode(tag); insertFilesIntoNode(files, baseNode); } @@ -255,7 +261,7 @@ public class TreeModelBuilder { return baseNode; } - private void insertFilesIntoNode(final List files, ChangesBrowserNode baseNode) { + private void insertFilesIntoNode(@NotNull List files, ChangesBrowserNode baseNode) { final ChangesGroupingPolicy policy = createGroupingPolicy(); Collections.sort(files, VirtualFileHierarchicalComparator.getInstance()); @@ -285,7 +291,7 @@ public class TreeModelBuilder { assert file != null; // whether a folder does not matter final String path = file.getPath(); - final StaticFilePath pathKey = (! FileUtil.isAbsolute(path) || VcsUtil.isPathRemote(path)) ? + final StaticFilePath pathKey = ! FileUtil.isAbsolute(path) || VcsUtil.isPathRemote(path) ? new StaticFilePath(false, path, null) : new StaticFilePath(false, new File(file.getIOFile().getPath().replace('\\', '/')).getAbsolutePath(), file.getVirtualFile()); ChangesBrowserNode oldNode = myFoldersCache.get(pathKey.getKey()); @@ -313,13 +319,17 @@ public class TreeModelBuilder { final Change change = new Change(cr, cr, FileStatus.NOT_CHANGED); final String branchName = switchedRoots.get(vf); insertChangeNode(vf, policy, rootsHeadNode, new Computable() { + @Override public ChangesBrowserNode compute() { return new ChangesBrowserChangeNode(myProject, change, new ChangeNodeDecorator() { + @Override public void decorate(Change change, SimpleColoredComponent component, boolean isShowFlatten) { } + @Override public List> stressPartsOfFileName(Change change, String parentPath) { return null; } + @Override public void preDecorate(Change change, ChangesBrowserNodeRenderer renderer, boolean showFlatten) { renderer.append("[" + branchName + "] ", SimpleTextAttributes.GRAYED_BOLD_ATTRIBUTES); } @@ -363,6 +373,7 @@ public class TreeModelBuilder { private Computable defaultNodeCreator(final Object change) { return new Computable() { + @Override public ChangesBrowserNode compute() { return ChangesBrowserNode.create(myProject, change); } @@ -394,6 +405,7 @@ public class TreeModelBuilder { return ourInstance; } + @Override public int compare(ChangesBrowserNode node1, ChangesBrowserNode node2) { final int classdiff = node1.getSortWeight() - node2.getSortWeight(); if (classdiff != 0) return classdiff; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java index 277facd9601b..0f7cd85cee45 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java @@ -21,6 +21,7 @@ import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.MultiValuesMap; import com.intellij.openapi.vfs.VirtualFile; @@ -84,7 +85,7 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta XBreakpointBase[] breakpoints = getAllBreakpoints(); for (XBreakpointBase breakpoint : breakpoints) { XSourcePosition position = breakpoint.getSourcePosition(); - if (position != null && position.getFile() == file) { + if (position != null && Comparing.equal(position.getFile(), file)) { fireBreakpointChanged(breakpoint); } } diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AbsoluteAlignmentInUserInterface.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AbsoluteAlignmentInUserInterface.html index 0c6fe554d53c..b8f077cbb07b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AbsoluteAlignmentInUserInterface.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AbsoluteAlignmentInUserInterface.html @@ -2,6 +2,7 @@ This inspection reports usages of absolute alignment constants from AWT and Swing. Internationalized applications should make use of relative alignment, because it respects locale component orientation settings. +

New in 11, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractClassExtendsConcreteClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractClassExtendsConcreteClass.html index 868a2808ab65..048db14336ad 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractClassExtendsConcreteClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractClassExtendsConcreteClass.html @@ -1,6 +1,7 @@ This inspection reports abstract classes which extend concrete classes. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractClassNeverImplemented.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractClassNeverImplemented.html index fd0f4e470173..f376345bc0a6 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractClassNeverImplemented.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractClassNeverImplemented.html @@ -2,6 +2,7 @@ This inspection reports abstract classes which have no concrete subclasses. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractClassWithOnlyOneDirectInheritor.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractClassWithOnlyOneDirectInheritor.html index 89c145e384c1..b3e221670183 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractClassWithOnlyOneDirectInheritor.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractClassWithOnlyOneDirectInheritor.html @@ -7,6 +7,7 @@ This inspection reports abstract classes which have precisely one direct inheritor. While such classes may offer admirable clarity of design, in memory-constrained or bandwidth-limited environments, they needlessly increase the total footprint of the application. Consider merging the abstract class with its inheritor. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractClassWithoutAbstractMethods.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractClassWithoutAbstractMethods.html index 470a37236cf5..5b4a91ebfa03 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractClassWithoutAbstractMethods.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractClassWithoutAbstractMethods.html @@ -1,6 +1,7 @@ This inspection reports abstract classes without abstract methods. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractMethodCallInConstructor.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractMethodCallInConstructor.html index d87305f238a8..d48a2e44b3e8 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractMethodCallInConstructor.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractMethodCallInConstructor.html @@ -3,6 +3,7 @@ This inspection reports any calls of abstract methods within a constructor of an abstract class. Such calls may result in subtle bugs, as the object is not guaranteed to be initialized before the method call occurs. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractMethodOverridesAbstractMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractMethodOverridesAbstractMethod.html index 59e628bae7ef..414cf09d5f8b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractMethodOverridesAbstractMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractMethodOverridesAbstractMethod.html @@ -3,6 +3,7 @@ This inspection reports abstract methods which override abstract methods. Methods with different return types or exception declarations than the method they override are not reported by this inspection. +

Use the first checkbox to ignore any abstract methods that have a different JavaDoc comment than their super method.

diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractMethodOverridesConcreteMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractMethodOverridesConcreteMethod.html index 1f15cb07345e..e24f5d3730bf 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractMethodOverridesConcreteMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractMethodOverridesConcreteMethod.html @@ -3,6 +3,7 @@ This inspection reports abstract methods which override concrete methods. Methods overridden from java.lang.Object are not reported by this inspection. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractMethodWithMissingImplementations.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractMethodWithMissingImplementations.html index a18d8093c7c3..e82aaf50701c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractMethodWithMissingImplementations.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AbstractMethodWithMissingImplementations.html @@ -3,6 +3,7 @@ This inspection reports any abstract methods which are not implemented in every concrete subclass. This is a compile-time error on the subclasses, while this inspection reports the problem at the point of the abstract method. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AccessToNonThreadSafeStaticFieldFromInstance.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AccessToNonThreadSafeStaticFieldFromInstance.html index 14d14e7a8380..c8d7b9c1d532 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AccessToNonThreadSafeStaticFieldFromInstance.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AccessToNonThreadSafeStaticFieldFromInstance.html @@ -4,6 +4,7 @@ This inspection reports on any access to a static field of any non-threadsafe type specified below, which is accessed from an instance field or a non-synchronized block. It is possible that the static field is accessed from multiple threads, which can lead to unspecified side effects. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AccessToStaticFieldLockedOnInstance.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AccessToStaticFieldLockedOnInstance.html index 334eda0f1275..f25162ddaf7e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AccessToStaticFieldLockedOnInstance.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AccessToStaticFieldLockedOnInstance.html @@ -4,6 +4,7 @@ This inspection reports on any access to a non-constant static field whic locked on either this or an instance field of this. Locking a static field on instance data does not prevent the field from being modified by other instances, and thus may result in surprising race conditions. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AmbiguousFieldAccess.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AmbiguousFieldAccess.html index 518bf5786448..feeb51174161 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AmbiguousFieldAccess.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AmbiguousFieldAccess.html @@ -17,6 +17,7 @@ accessed, when in fact a field from the super class is accessed. To make the int } } +

New in 11, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AmbiguousMethodCall.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AmbiguousMethodCall.html index fa898a0e53ce..60f14823a34a 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AmbiguousMethodCall.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AmbiguousMethodCall.html @@ -6,6 +6,7 @@ reader of the code may think that a method in the surrounding class is called, when in fact a method from the super class is called. To make the intent of the code more clear it is recommended to add a super qualifier to the method call. +

New in 8, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/Annotation.html b/plugins/InspectionGadgets/src/inspectionDescriptions/Annotation.html index 7bb4b064b597..8897b1eb04ce 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/Annotation.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/Annotation.html @@ -2,6 +2,7 @@ This inspection reports any uses of annotations. Annotations are not supported under Java 1.4 or earlier JVMs. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AnnotationClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AnnotationClass.html index 84cecfd3336d..9500c4943f26 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AnnotationClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AnnotationClass.html @@ -2,6 +2,7 @@ This inspection reports annotation interfaces. Such interfaces are not supported under Java 1.4 or earlier JVMs. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AnnotationNamingConvention.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AnnotationNamingConvention.html index 9af470b9df5d..66ec962d05db 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AnnotationNamingConvention.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AnnotationNamingConvention.html @@ -2,6 +2,7 @@ This inspection reports annotation classes whose names are either too short, too long, or do not follow the specified regular expression pattern. +

Use the fields provided below to specify minimum length, maximum length and regular expression expected for annotation names. (Regular expressions are in standard java.util.regex format.) diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AnonymousClassComplexity.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AnonymousClassComplexity.html index ee8cd0bea250..b191aa95ca6a 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AnonymousClassComplexity.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AnonymousClassComplexity.html @@ -5,6 +5,7 @@ total complexity of a class is the sum of the cyclomatic complexities of all the and initializers the class declares. Inherited methods and initializers are not counted toward the total complexity. Anonymous classes with more than very low complexities may be difficult to understand, and should probably be promoted to become named inner classes. +

Use the field provided below to specify the maximum acceptable complexity a class might have.

diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AnonymousClassMethodCount.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AnonymousClassMethodCount.html index 97e0e4d793ad..4263cb93b908 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AnonymousClassMethodCount.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AnonymousClassMethodCount.html @@ -3,6 +3,7 @@ This inspection reports anonymous inner class with too many methods. Anonymous classes with more than a very low number of methods may be difficult to understand, and should probably be promoted to become named inner classes. +

Use the field provided below to specify the maximum acceptable number of methods an anonymous inner class might have. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AnonymousClassVariableHidesContainingMethodVariable.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AnonymousClassVariableHidesContainingMethodVariable.html index 356643a15074..06f514b4b017 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AnonymousClassVariableHidesContainingMethodVariable.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AnonymousClassVariableHidesContainingMethodVariable.html @@ -2,6 +2,7 @@ This inspection reports anonymous class variables being named identically to variables of a containing method. Such a variable name may be confusing. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AnonymousInnerClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AnonymousInnerClass.html index bc68d7ee018b..32a72153d559 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AnonymousInnerClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AnonymousInnerClass.html @@ -2,6 +2,7 @@ This inspection reports any anonymous inner classes. Some code standards discourage the use of anonymous inner classes. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AnonymousInnerClassMayBeStatic.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AnonymousInnerClassMayBeStatic.html index 74bc025cb1d9..c9d5655ba410 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AnonymousInnerClassMayBeStatic.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AnonymousInnerClassMayBeStatic.html @@ -6,6 +6,7 @@ Applying the results of this inspection without consideration might have negativ This inspection reports any anonymous inner classes which may safely be made into a named static inner class. An inner class may be static if it doesn't reference its enclosing class instance or local variables. A static inner class uses slightly less memory. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ArchaicSystemPropertyAccess.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ArchaicSystemPropertyAccess.html index 77358237aa64..379e16d4eed6 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ArchaicSystemPropertyAccess.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ArchaicSystemPropertyAccess.html @@ -5,6 +5,7 @@ These methods fetch integer and boolean values from the system properties for a given key. Due to their underexpressive names and confusing location of functionality, it's easy for novice programmers to attempt to use these for other purposes, such as string parsing. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayEquality.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayEquality.html index 515d2d82489e..5254963d52e0 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayEquality.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayEquality.html @@ -2,6 +2,7 @@ This inspection reports any use of == to test for Array equality, rather than the "java.util.Arrays.equals()" method. +

New in 10.5, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayEquals.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayEquals.html index 92b1fc1a0411..f669c81c2393 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayEquals.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayEquals.html @@ -6,6 +6,7 @@ compares identity and is equivalent to using ==. Use Arrays.equals() to compare the contents of two arrays or Arrays.deepEquals() to compare the content of two multi-dimensional arrays. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayHashCode.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayHashCode.html index 49642c20b1bf..7612809e4a6b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayHashCode.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayHashCode.html @@ -5,6 +5,7 @@ on an array. To get the same hash code for two arrays with identical contents call Arrays.hashCode(). Use Arrays.deepHashCode() to calculate the hash code of a multi-dimensional array. +

New in 10.5, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayLengthInLoopCondition.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayLengthInLoopCondition.html index 1883c98409af..7530079c4a06 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayLengthInLoopCondition.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayLengthInLoopCondition.html @@ -6,6 +6,7 @@ Applying the results of this inspection without consideration might have negativ This inspection reports any access to the .length of an array in the condition part of a loop statement. In highly resource constrained environments, such calls may have adverse performance implications. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AssertAsName.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AssertAsName.html index c4e8d1aee496..e1f3f3d7ac2d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AssertAsName.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AssertAsName.html @@ -3,6 +3,7 @@ This inspection reports variables, methods, or classes named assert. Such names are legal under Java 1.3 or earlier JVMs, but will cause problems under Java 1.4 or later. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AssertEqualsBetweenInconvertibleTypes.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AssertEqualsBetweenInconvertibleTypes.html index ce90a6b186d2..105ecb0a2b50 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AssertEqualsBetweenInconvertibleTypes.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AssertEqualsBetweenInconvertibleTypes.html @@ -3,6 +3,7 @@ This inspection reports any calls to JUnit's assertEquals() method where the expected result and actual result arguments are of incompatible types. While such a call might theoretically be useful, most likely it represents a bug. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AssertEqualsCalledOnArray.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AssertEqualsCalledOnArray.html index f34e7ddd8b12..1da4deb18939 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AssertEqualsCalledOnArray.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AssertEqualsCalledOnArray.html @@ -3,6 +3,7 @@ This inspection reports any calls to JUnit's assertEquals() method with arguments of type array. Arrays should be checked with one of the assertArrayEquals() methods. +

New in 10, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AssertEqualsMayBeAssertSame.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AssertEqualsMayBeAssertSame.html index d815fe39527e..08f1a1eaf99e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AssertEqualsMayBeAssertSame.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AssertEqualsMayBeAssertSame.html @@ -5,6 +5,7 @@ or junit.framework.Assert.assertEquals() which can be replaced with an equivalent call to assertSame(). This is possible when the arguments are instances of a final class which does not override the equals() method. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AssertStatement.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AssertStatement.html index 8598d4225318..4f9996911b21 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AssertStatement.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AssertStatement.html @@ -2,6 +2,7 @@ This inspection reports assert statements. Such statements are not supported under Java 1.3 or earlier JVMs. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AssertWithSideEffects.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AssertWithSideEffects.html index b29e404d6345..cd9b6022fe1f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AssertWithSideEffects.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AssertWithSideEffects.html @@ -6,6 +6,7 @@ switched off, the side effects are not guaranteed to happen and can cause subtle Common unwanted side effects detected by this inspection are modifications of variables and fields in the assert statement. Also methods called are analyzed one level deep for any modifications of fields. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AssertsWithoutMessages.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AssertsWithoutMessages.html index 7a6139c9fcee..32d7b0725db0 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AssertsWithoutMessages.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AssertsWithoutMessages.html @@ -4,6 +4,7 @@ This inspection reports calls to JUnit assertXXX() or fail() methods that don't report an error message on assertion failure. Error messages may help clarify the test case's intent. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToCatchBlockParameter.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToCatchBlockParameter.html index d192f2059d9f..ae41b029cd0f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToCatchBlockParameter.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToCatchBlockParameter.html @@ -2,6 +2,7 @@ This inspection reports assignment to variable declared as a catch block parameter. While occasionally intended, this construct can be confusing. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToCollectionFieldFromParameter.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToCollectionFieldFromParameter.html index ec4da1895826..e57073ae82ab 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToCollectionFieldFromParameter.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToCollectionFieldFromParameter.html @@ -4,6 +4,7 @@ This inspection reports any attempt to assign an array or Collection fiel Since the array or Collection may have its contents modified by the calling method, this construct may result in an object having its state modified unexpectedly. While occasionally useful for performance reasons, this construct is inherently bug-prone. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToDateFieldFromParameter.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToDateFieldFromParameter.html index 996256b609ac..44a64b0083fc 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToDateFieldFromParameter.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToDateFieldFromParameter.html @@ -6,6 +6,7 @@ Since Date or Calendar are often treated as immutable values but are actually mutable, assigning to such a field from a method parameter may result in an object having its state modified unexpectedly. While occasionally useful for performance reasons, this construct is inherently bug-prone. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToForLoopParameter.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToForLoopParameter.html index 1c3da4526ea5..c11f72964547 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToForLoopParameter.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToForLoopParameter.html @@ -3,6 +3,7 @@ This inspection reports assignment a variable declared in a for statement in the body of that statement. It also reports any attempt to increment or decrement the variable. While occasionally intended, this construct can be extremely confusing, and is often the result of a typo. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToMethodParameter.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToMethodParameter.html index 6b294eaea87a..4b011915e702 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToMethodParameter.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToMethodParameter.html @@ -3,6 +3,7 @@ This inspection reports assignment to a variable declared as a method parameter. It also reports any attempt to increment or decrement the variable. While occasionally intended, this construct can be extremely confusing, and is often the result of a typo. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToNull.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToNull.html index 00614fa625bb..f334cf99cafc 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToNull.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToNull.html @@ -6,6 +6,7 @@ While occasionally useful for triggering garbage collection, this construct may make the code more prone to NullPointerExceptions, and often indicates that the developer doesn't really understand the class's intended semantics. +

Use the checkbox below to ignore assignments to fields.

diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToStaticFieldFromInstanceMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToStaticFieldFromInstanceMethod.html index 6ac0c60b221a..24bbbda8b706 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToStaticFieldFromInstanceMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToStaticFieldFromInstanceMethod.html @@ -4,6 +4,7 @@ This inspection reports any assignments to static fields from within instance methods. While legal, such assignments are tricky to do safely, and are often a result of fields being inadvertently marked static. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentUsedAsCondition.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentUsedAsCondition.html index f9316671b1e8..0fdc942c68be 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentUsedAsCondition.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentUsedAsCondition.html @@ -5,6 +5,7 @@ used as the condition of an if, while, for or do statement. While occasionally intended, this usage is confusing, and often indicates a typo (= instead of ==). +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AutoBoxing.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AutoBoxing.html index 154738defc78..a0a76015fe51 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AutoBoxing.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AutoBoxing.html @@ -2,6 +2,7 @@ This inspection reports "auto-boxing", i.e. the automatic wrapping of primitive values as objects, where needed. Code which relies on auto-boxing will not work in pre-Java 5.0 environments. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AutoUnboxing.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AutoUnboxing.html index d79729b6c17a..30d5516e3e36 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AutoUnboxing.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AutoUnboxing.html @@ -2,6 +2,7 @@ This inspection reports "auto-unboxing", e.g. the automatic unwrapping of objects into primitive values, where needed. Code which relies on auto-boxing will not work in pre-Java 5.0 environments. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AwaitNotInLoop.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AwaitNotInLoop.html index 89c6ddbaab1c..1e1a328988f3 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AwaitNotInLoop.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AwaitNotInLoop.html @@ -4,6 +4,7 @@ This inspection reports on any call to java.util.concurrent.locks.Condition.a await() and related methods are normally used to suspend a thread until a condition is signalled as true, and that condition should be checked after the await() returns. A loop is the clearest way to achieve this. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AwaitWithoutCorrespondingSignal.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AwaitWithoutCorrespondingSignal.html index 721ffcb429db..484570eb4cf1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AwaitWithoutCorrespondingSignal.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AwaitWithoutCorrespondingSignal.html @@ -4,6 +4,7 @@ This inspection reports on any call to Condition.signal() or Condition.signalAll() for which no call to a corresponding Condition.await() can be found. Only calls which target fields of the current class are reported by this inspection. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/BadExceptionCaught.html b/plugins/InspectionGadgets/src/inspectionDescriptions/BadExceptionCaught.html index 0c2de6e6dee8..aaf157e4ec57 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/BadExceptionCaught.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/BadExceptionCaught.html @@ -5,6 +5,7 @@ which catch inappropriate exceptions. Some exceptions, for instance java.lang.NullPointerException and java.lang.IllegalMonitorStateException represent programming errors and so should almost certainly not be caught in production code. +

Use the list below to specify which exceptions should be flagged by this inspection.

diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/BadExceptionThrown.html b/plugins/InspectionGadgets/src/inspectionDescriptions/BadExceptionThrown.html index ef78174d641a..1dbe08a6c3c0 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/BadExceptionThrown.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/BadExceptionThrown.html @@ -3,8 +3,8 @@ This inspection reports throw statements which throw inappropriate exceptions. One use of this inspection would be to warn of throw statements which throw overly generic exceptions -(e.g. java.lang.Exception or -java.io.IOException). +(e.g. java.lang.Exception or java.io.IOException). +

Use the list below to specify which exceptions should be flagged by this inspection.

diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/BadOddness.html b/plugins/InspectionGadgets/src/inspectionDescriptions/BadOddness.html index 6e0616a2ac02..e3be8a7b2960 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/BadOddness.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/BadOddness.html @@ -4,6 +4,7 @@ This inspection reports any checks for oddness of the form:

x % 2 == 1
Such checks will fail for negative odd values, which is probably not the behaviour intended. Consider using:
x % 2 != 0
or:
(x & 1) == 1
instead. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/BeforeClassOrAfterClassIsPublicStaticVoidNoArg.html b/plugins/InspectionGadgets/src/inspectionDescriptions/BeforeClassOrAfterClassIsPublicStaticVoidNoArg.html index c50a5cd30489..660b1c41bdc3 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/BeforeClassOrAfterClassIsPublicStaticVoidNoArg.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/BeforeClassOrAfterClassIsPublicStaticVoidNoArg.html @@ -4,6 +4,7 @@ This inspection reports JUnit 4.0 @BeforeClass or @AfterClass meth is not declared public static, does not return void, or takes arguments. Such methods are easy to create inadvertently, and will not be executed by JUnit tests runners. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/BeforeOrAfterIsPublicVoidNoArg.html b/plugins/InspectionGadgets/src/inspectionDescriptions/BeforeOrAfterIsPublicVoidNoArg.html index 6a3d7db65f8e..5e60068122c0 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/BeforeOrAfterIsPublicVoidNoArg.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/BeforeOrAfterIsPublicVoidNoArg.html @@ -4,6 +4,7 @@ This inspection reports JUnit 4.0 @Before or @After method is not declared public, does not return void, or takes arguments. Such methods are easy to create inadvertently, and will not be executed by JUnit tests runners. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/BigDecimalEquals.html b/plugins/InspectionGadgets/src/inspectionDescriptions/BigDecimalEquals.html index f12bc93fc09c..96e143dc66eb 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/BigDecimalEquals.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/BigDecimalEquals.html @@ -6,6 +6,7 @@ a mistake, as two java.math.BigDecimals are only equal if they are equal in both value and scale, so that 2.0 is not equal to 2.00 To compare java.math.BigDecimals for mathematical equality, use .compareTo() instead. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/BooleanConstructor.html b/plugins/InspectionGadgets/src/inspectionDescriptions/BooleanConstructor.html index b87e1287a3b4..389c43c7bcd2 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/BooleanConstructor.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/BooleanConstructor.html @@ -3,6 +3,7 @@ This inspection reports any attempt to instantiate a new Boolean object. Constructing new Boolean objects is rarely necessary, and may cause performance problems if done often enough. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/BooleanMethodIsAlwaysInverted.html b/plugins/InspectionGadgets/src/inspectionDescriptions/BooleanMethodIsAlwaysInverted.html index 11f718f197a3..e2e25891201b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/BooleanMethodIsAlwaysInverted.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/BooleanMethodIsAlwaysInverted.html @@ -19,5 +19,8 @@ For example: boolean member = !inverted(); } + +

+Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/BooleanMethodNameMustStartWithQuestion.html b/plugins/InspectionGadgets/src/inspectionDescriptions/BooleanMethodNameMustStartWithQuestion.html index f1e2d1c1b6a9..a6ee832de6b9 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/BooleanMethodNameMustStartWithQuestion.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/BooleanMethodNameMustStartWithQuestion.html @@ -2,6 +2,7 @@ This inspection reports boolean methods whose names do not start with a question word. Boolean methods that override library methods are ignored by this inspection. +

Use the list below to specify acceptable question words to start boolean method names with.

diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/BooleanVariableAlwaysNegated.html b/plugins/InspectionGadgets/src/inspectionDescriptions/BooleanVariableAlwaysNegated.html index 36b2465631f9..745938fe47c1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/BooleanVariableAlwaysNegated.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/BooleanVariableAlwaysNegated.html @@ -2,6 +2,7 @@ This inspection reports any boolean variables or fields which are always negated when its value is used. +

New in 11, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/BoxingBoxedValue.html b/plugins/InspectionGadgets/src/inspectionDescriptions/BoxingBoxedValue.html index 467db0f35383..6fa5b3092cb9 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/BoxingBoxedValue.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/BoxingBoxedValue.html @@ -4,6 +4,7 @@ This inspection reports boxing of already boxed values. This is a useless operation since any boxed value will first be auto-unboxed before boxing the value again. If done inside an inner loop such code may cause performance problems. +

New in 10.0.2, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/BreakStatement.html b/plugins/InspectionGadgets/src/inspectionDescriptions/BreakStatement.html index 33a4ac0dda8f..2167c84064b0 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/BreakStatement.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/BreakStatement.html @@ -3,6 +3,7 @@ This inspection reports break statements, other than at the end of a switch statement branch. break statements complicate refactoring, and can be confusing. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/BreakStatementWithLabel.html b/plugins/InspectionGadgets/src/inspectionDescriptions/BreakStatementWithLabel.html index 5d6ca8ad33f8..6b9578dcea8b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/BreakStatementWithLabel.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/BreakStatementWithLabel.html @@ -2,6 +2,7 @@ This inspection reports break statements with labels. Labeled break statements complicate refactoring, and can be confusing. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/BusyWait.html b/plugins/InspectionGadgets/src/inspectionDescriptions/BusyWait.html index fbc3b07caa47..5914fcf7db7c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/BusyWait.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/BusyWait.html @@ -3,6 +3,7 @@ This inspection reports calls to java.lang.Thread.sleep() that occur inside loops. Such calls are indicative of "busy-waiting". Busy-waiting is often inefficient, and may result in unexpected deadlocks as busy-waiting threads do not release locked resources. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CStyleArrayDeclaration.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CStyleArrayDeclaration.html index 6cbcb96a1ccd..40b3e09db8e6 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CStyleArrayDeclaration.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CStyleArrayDeclaration.html @@ -2,6 +2,7 @@ This inspection reports array declarations made using C-style syntax, with the array indicator attached to the variable, rather than Java-style syntax, with the array indicator attached to the type. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CachedNumberConstructorCall.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CachedNumberConstructorCall.html index 08f1bd96587a..1b76b03a4c3e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CachedNumberConstructorCall.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CachedNumberConstructorCall.html @@ -12,6 +12,7 @@ here (introduced in Java 5), which will cache objects for values between -128 an

This inspection only reports if the project or module is configured to use a language level of 5.0 or higher. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CallToNativeMethodWhileLocked.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CallToNativeMethodWhileLocked.html index 9e68e81a5f1b..817aebc8d27f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CallToNativeMethodWhileLocked.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CallToNativeMethodWhileLocked.html @@ -3,6 +3,7 @@ This inspection reports any to methods declared native while in a synchronized block or method. While not necessarily representing a problem, such calls cause an expensive context switch, and are best kept out of synchronized contexts, if possible. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CallToSimpleGetterInClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CallToSimpleGetterInClass.html index 576709e57737..8ed084450224 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CallToSimpleGetterInClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CallToSimpleGetterInClass.html @@ -5,6 +5,7 @@ A simple property getter is defined as one which simply returns the value of a f and does no other calculation. Such simple getter calls may be safely inlined, at a small performance improvement. Some coding standards also suggest against the use of simple getters for code clarity reasons. +

Use the first option below to only report on getter calls on this, not on objects of the same type passed in as a parameter. Use the second option below to only report when the getter is private. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CallToSimpleSetterInClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CallToSimpleSetterInClass.html index ebb3f161ab44..0ae86f62cf09 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CallToSimpleSetterInClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CallToSimpleSetterInClass.html @@ -5,6 +5,7 @@ A simple property setter is defined as one which simply assigns the value of its and does no other calculation. Such simple setter calls may be safely inlined, at a small performance improvement. Some coding standards also suggest against the use of simple setters for code clarity reasons. +

Use the first option below to only report on setter calls on this, not on objects of the same type passed in as a parameter. Use the second option below to only report when the setter is private. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CallToStringConcatCanBeReplacedByOperator.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CallToStringConcatCanBeReplacedByOperator.html index 0e495d67d783..c061a1cd1d3e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CallToStringConcatCanBeReplacedByOperator.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CallToStringConcatCanBeReplacedByOperator.html @@ -4,6 +4,7 @@ This inspection reports calls to the concat method of a java.lang.String object. Such calls can be replaced with the '+' operator for increased code clarity and possible increased performance if the method was invoked on a constant with a constant argument. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CastConflictsWithInstanceof.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CastConflictsWithInstanceof.html index 3866a6ba6711..2f767e6bb496 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CastConflictsWithInstanceof.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CastConflictsWithInstanceof.html @@ -4,6 +4,7 @@ This inspection reports type cast expressions which are surrounded by an instanceof check for a different type. While it is possible that this was intended, such a construct is most likely an error, and will result in a java.lang.ClassCastException at runtime. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CastThatLosesPrecision.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CastThatLosesPrecision.html index e2fee302d0b2..dc07dbae4ce3 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CastThatLosesPrecision.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CastThatLosesPrecision.html @@ -3,6 +3,7 @@ This inspection reports any cast operations between built-in numeric types which may result in loss of precision. Such casts are not necessarily a problem, but may result in difficult to trace bugs if the loss of precision is unexpected. +

Use the checkbox below to indicate that this inspection should ignore casts from int to char. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CastToConcreteClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CastToConcreteClass.html index d60375df2567..069e856eb04d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CastToConcreteClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CastToConcreteClass.html @@ -3,6 +3,7 @@ This inspection reports casting a value to a concrete class, rather than an interface. Such declarations may represent a failure of abstraction, and may make testing more difficult. Declarations whose classes come from system or third-party libraries will not be reported by this inspection. +

Use the checkbox below to have this inspection ignore casts to abstract classes.

diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CastToIncompatibleInterface.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CastToIncompatibleInterface.html index 3d92b0341c9e..06614592084d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CastToIncompatibleInterface.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CastToIncompatibleInterface.html @@ -5,6 +5,7 @@ the cast type is an interface, and the cast expression has a class type which ne implements the cast interface, nor has any visible subclasses which implement or extend the cast interface. While it is possible that this was intended, such a construct is most likely an error, and will result in a java.lang.ClassCastException at runtime. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CaughtExceptionImmediatelyRethrown.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CaughtExceptionImmediatelyRethrown.html index 22176ac97d66..9c9ce6a716b0 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CaughtExceptionImmediatelyRethrown.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CaughtExceptionImmediatelyRethrown.html @@ -4,6 +4,7 @@ This inspection reports any catch block where the caught exception is immediately rethrown, without performing any action on it. Such catch blocks are unnecessary or lack error handling. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ChainedEquality.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ChainedEquality.html index d6d3170e1fc2..6812f317f5c7 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ChainedEquality.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ChainedEquality.html @@ -2,6 +2,7 @@ This inspection reports chained equality comparisons (i.e. a==b==c). Such comparisons are confusing. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ChainedMethodCall.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ChainedMethodCall.html index 7aac8c0d1c18..ce81b8cafe81 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ChainedMethodCall.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ChainedMethodCall.html @@ -2,6 +2,7 @@ This inspection reports method calls whose target is another method call. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ChannelResource.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ChannelResource.html index 43115d78dfc8..a8e093082073 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ChannelResource.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ChannelResource.html @@ -6,6 +6,7 @@ front of a try block and closed in the corresponding if an exception is thrown before the resource is closed. Channel resources reported by this inspection include any instances created by calling getChannel() on a file or socket resource. +

Use the checkbox below to specify if a Channel is allowed to be opened inside a try block. This style is less desirable because it is more verbose than opening a Channel diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CharUsedInArithmeticContext.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CharUsedInArithmeticContext.html index 58f550d8f89c..dabb5f1e72aa 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CharUsedInArithmeticContext.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CharUsedInArithmeticContext.html @@ -1,7 +1,8 @@ This inspection reports on any expressions of type char which are used in -addition or substraction expressions. +addition or subtraction expressions. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CharacterComparison.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CharacterComparison.html index c23a9ff79469..34aba2994513 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CharacterComparison.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CharacterComparison.html @@ -2,6 +2,7 @@ This inspection reports any ordinal comparison of char values. In an internationalized environment, such comparisons are rarely correct. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CheckForOutOfMemoryOnLargeArrayAllocation.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CheckForOutOfMemoryOnLargeArrayAllocation.html index 0a388ca6b0ba..aa05e43069d1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CheckForOutOfMemoryOnLargeArrayAllocation.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CheckForOutOfMemoryOnLargeArrayAllocation.html @@ -7,6 +7,7 @@ This inspection reports large array allocations which do not check for java.lang.OutOfMemoryError. In memory constrained environments, allocations of large data objects should probably be checked for memory depletion. +

Use the field below to specify the maximum number of elements to allow in unchecked array allocations. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CheckedExceptionClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CheckedExceptionClass.html index 927a3b5d8222..0efb2ee7f8f9 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CheckedExceptionClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CheckedExceptionClass.html @@ -3,6 +3,7 @@ This inspection reports checked exception classes (i.e. subclasses of Exception which are not also subclasses of RuntimeException). Certain coding standards require that all user-defined exception classes be unchecked. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassComplexity.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassComplexity.html index 376706f31842..00ebafea7f8e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassComplexity.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassComplexity.html @@ -4,6 +4,7 @@ This inspection reports class with too high of a total complexity. The total complexity of a class is the sum of the cyclomatic complexities of all the methods and initializers the class declares. Inherited methods and initializers are not counted toward the total complexity. +

Use the field provided below to specify the maximum acceptable complexity a class might have.

diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassCoupling.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassCoupling.html index 56ec7ca4ec11..aad0a34223e3 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassCoupling.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassCoupling.html @@ -4,6 +4,7 @@ This inspection reports classes which are highly coupled, i.e. that reference to Classes with too high a coupling can be very fragile, and should probably be broken up. References to system classes (those in the java.or javax. packages), are not counted for purposes of this inspection. +

Use the field provided below to specify the maximum acceptable coupling a class might have.

diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassEscapesItsScope.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassEscapesItsScope.html index 06ab66bd4e37..ea1dba9fb032 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassEscapesItsScope.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassEscapesItsScope.html @@ -5,6 +5,7 @@ be used outside the class's stated scope. For instance, this inspection would re a public method which returns a private inner class, or a protected field whose type is a package-visible class. While legal Java, such references can be very confusing, and make reuse difficult. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassInTopLevelPackage.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassInTopLevelPackage.html index ff0b74019efa..578d9a6ed77f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassInTopLevelPackage.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassInTopLevelPackage.html @@ -1,7 +1,7 @@ -This inspection reports any classes -which do not contain package declarations. +This inspection reports any classes which do not contain package declarations. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassIndependentOfModule.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassIndependentOfModule.html index 548a0eb5cfd1..fad2612e78cb 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassIndependentOfModule.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassIndependentOfModule.html @@ -3,6 +3,7 @@ This inspection reports any classes which are neither dependent on nor depended on by other classes in their module. Such classes are an indication of ad-hoc or incoherent modularisation strategies, and may often profitably be moved. +

New in 11, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassInheritanceDepth.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassInheritanceDepth.html index 143bfa2cf8fe..e8cac019fb33 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassInheritanceDepth.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassInheritanceDepth.html @@ -3,6 +3,7 @@ This inspection reports class too deep in the inheritance hierarchy. Classes too deeply inherited may be confusing, and are a good sign that refactoring may be necessary. This inspection counts all superclasses from a library as a single superclass (libraries are considered unmodifyable). +

Use the field provided below to specify the maximum acceptable inheritance depth a class might have.

diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassInitializer.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassInitializer.html index ef4b5d2e08c5..c025f4363921 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassInitializer.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassInitializer.html @@ -5,6 +5,7 @@ in classes. Some coding standards prohibit such initializers, preferring initial in constructors or field initializers. Non-static initializers may also be inadvertently created by deleting the static keyword, resulting in obscure bugs. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassInitializerMayBeStatic.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassInitializerMayBeStatic.html index eda8ff5e553b..6cb2f1a5e170 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassInitializerMayBeStatic.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassInitializerMayBeStatic.html @@ -3,6 +3,7 @@ This inspection reports any class initializers which may safely be made static. A class initializer may be static if it does not reference any of its class' non static methods and non static fields. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassLoaderInstantiation.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassLoaderInstantiation.html index 60086b4963be..fb5c27f1562b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassLoaderInstantiation.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassLoaderInstantiation.html @@ -2,6 +2,7 @@ This inspection reports any instantiations of java.lang.ClassLoader objects. While often benign, any instantiations to ClassLoader should be closely examined in any security audit. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassMayBeInterface.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassMayBeInterface.html index 4ecb71331ef9..ad6a8bf70637 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassMayBeInterface.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassMayBeInterface.html @@ -5,6 +5,7 @@ which may be simplified to be interfaces. This occurs if the class has no superc than Object), has no fields declared that are not static, final, and public, and has no methods declared that are not public and abstract, and no inner classes that cannot themselves be interfaces. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNameDiffersFromFileName.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNameDiffersFromFileName.html index 6eb4befbd3ee..84535104efe2 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNameDiffersFromFileName.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNameDiffersFromFileName.html @@ -4,6 +4,7 @@ This inspection reports top-level class names which do not match the name of their containing file. While the Java specification allows such naming for non-public classes, such misnamed files can be confusing, and may degrade the usefulness of various software tools. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNamePrefixedWithPackageName.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNamePrefixedWithPackageName.html index f36fb26678f5..7526c9c23a86 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNamePrefixedWithPackageName.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNamePrefixedWithPackageName.html @@ -3,6 +3,7 @@ This inspection reports classes whose names are prefixed with their package names, irrespective of capitalization. While occasionally reasonable, this is often due to a poor naming scheme, and may be redundant and annoying. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNameSameAsAncestorName.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNameSameAsAncestorName.html index c374462f3a35..f9534e094437 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNameSameAsAncestorName.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNameSameAsAncestorName.html @@ -2,6 +2,7 @@ This inspection reports class being named identically to one of their super classes (but in different packages). Such class name may be very confusing. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNamingConvention.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNamingConvention.html index e549b93e43b1..3d546fcca311 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNamingConvention.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNamingConvention.html @@ -2,6 +2,7 @@ This inspection reports classes whose names are either too short, too long, or do not follow the specified regular expression pattern. +

Use the fields provided below to specify minimum length, maximum length and regular expression expected for class names. (Regular expressions are in standard java.util.regex format.) diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNestingDepth.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNestingDepth.html index 5253fa6ba020..63601806d7c3 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNestingDepth.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNestingDepth.html @@ -2,6 +2,7 @@ This inspection reports inner classes too deeply nested. Nesting inner classes inside inner classes is almost certain to be confusing, and is a good sign that refactoring may be necessary. +

Use the field provided below to specify the maximum acceptable nesting depth a class might have.

diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNewInstance.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNewInstance.html index 023dca135e4d..e5a5afcff1a5 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNewInstance.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassNewInstance.html @@ -9,6 +9,7 @@ would otherwise be performed by the compiler. Replacing such a method call with a call to the java.lang.reflect.Constructor.newInstance() method avoids this problem by wrapping any exception thrown by the constructor in a java.lang.reflect.InvocationTargetException. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassOnlyUsedInOneModule.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassOnlyUsedInOneModule.html index 4bb0226ff370..8be138e1b330 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassOnlyUsedInOneModule.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassOnlyUsedInOneModule.html @@ -3,6 +3,7 @@ This inspection reports any classes which is only depended on and only depends on one module which is different from the module containing the class. Such class could be moved into that module. +

New in 11, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassOnlyUsedInOnePackage.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassOnlyUsedInOnePackage.html index 4bb0226ff370..8be138e1b330 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassOnlyUsedInOnePackage.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassOnlyUsedInOnePackage.html @@ -3,6 +3,7 @@ This inspection reports any classes which is only depended on and only depends on one module which is different from the module containing the class. Such class could be moved into that module. +

New in 11, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassReferencesSubclass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassReferencesSubclass.html index bef4133e6e7a..dc8ed7f6ee5d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassReferencesSubclass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassReferencesSubclass.html @@ -2,6 +2,7 @@ This inspection reports classes which contain references to one of their subclasses. Such references may be confusing, and violate several rules of object-oriented design. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassUnconnectedToPackage.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassUnconnectedToPackage.html index 5e79e8324dcd..1abda8015376 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassUnconnectedToPackage.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassUnconnectedToPackage.html @@ -3,6 +3,7 @@ This inspection reports any classes which are neither dependent on nor depended on by other classes in their package. Such classes are an indication of ad-hoc or incoherent packaging strategies, and may often profitably be moved. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithTooManyDependencies.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithTooManyDependencies.html index 74072cfd9ca9..0fbaf1825ed9 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithTooManyDependencies.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithTooManyDependencies.html @@ -5,6 +5,7 @@ other classes in the project. Such classes may be prone to instability, as modif to any of the classes it is dependent on may require changing the class. Only top-level classes are reported by this inspection. Since this inspection requires global code analysis, it is only available in batch inspection mode. +

Use the field below to specify the maximum number of dependencies a class may have before triggering this inspection diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithTooManyDependents.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithTooManyDependents.html index fbf5875e4760..34b3bebba348 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithTooManyDependents.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithTooManyDependents.html @@ -4,6 +4,7 @@ This global inspection reports any classes on which too many other classes in yo are directly dependent. Such classes may be expensive to modify, as changes to the class may require changing many other classes. Only top-level classes are reported by this inspection. Since this inspection requires global code analysis, it is only available in batch inspection mode. +

Use the field below to specify the maximum number of dependents a class may have before triggering this inspection diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithTooManyTransitiveDependencies.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithTooManyTransitiveDependencies.html index 21bff8bcd422..92d7b98e32ca 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithTooManyTransitiveDependencies.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithTooManyTransitiveDependencies.html @@ -5,6 +5,7 @@ on too many other classes in your project. Such classes may be prone to instabil as changes to any of the classes it is dependent on may require changing the class. Only top-level classes are reported by this inspection. Since this inspection requires global code analysis, it is only available in batch inspection mode. +

Use the field below to specify the maximum number of direct or indirect dependencies a class may have before triggering this inspection diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithTooManyTransitiveDependents.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithTooManyTransitiveDependents.html index 81c5dd40a3ea..839a4e3a7445 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithTooManyTransitiveDependents.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithTooManyTransitiveDependents.html @@ -5,6 +5,7 @@ project are directly or indirectly dependent. Such classes may be expensive to m as changes to the class may require changing many other classes. Only top-level classes are reported by this inspection. Since this inspection requires global code analysis, it is only available in batch inspection mode. +

Use the field below to specify the maximum number of direct or indirect dependents a class may have before triggering this inspection diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithoutConstructor.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithoutConstructor.html index 7dcf655024b0..0373ecd8210d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithoutConstructor.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithoutConstructor.html @@ -1,6 +1,7 @@ This inspection reports a classes without constructors. Some coding standards prohibit such classes. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithoutNoArgConstructor.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithoutNoArgConstructor.html index cc2e26fab2ce..58b5fecd7587 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithoutNoArgConstructor.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ClassWithoutNoArgConstructor.html @@ -2,6 +2,7 @@ This inspection reports a classes without a no-argument constructor. Such constructors are necessary in some contexts if a class is to be created reflexively. +

Use the checkbox below to indicate that this inspection should ignore classes which contain no explicit constructors, and thus are provided a default no-argument constructor diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CloneCallsConstructors.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CloneCallsConstructors.html index a18f77cb4399..5485e24002b7 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CloneCallsConstructors.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CloneCallsConstructors.html @@ -3,6 +3,7 @@ This inspection reports calls to object constructors inside clone() methods. Instantiation of objects inside of clone() should be done by calling clone(), instead of creating the object directly, to support later subclassing. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CloneCallsSuperClone.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CloneCallsSuperClone.html index e7852b9dd38f..6081126dc5bf 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CloneCallsSuperClone.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CloneCallsSuperClone.html @@ -2,6 +2,7 @@ This inspection reports clone() methods which do not call super.clone(). Cloning an object without calling super.clone() may result in objects being improperly initialized. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CloneDeclaresCloneNotSupported.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CloneDeclaresCloneNotSupported.html index 36a057214b78..aeb3274a2954 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CloneDeclaresCloneNotSupported.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CloneDeclaresCloneNotSupported.html @@ -6,6 +6,7 @@ to possibly throw CloneNotSupportedException, then subclasses which need prohibit cloning will not be able to do so in the standard way. This inspection will not report clone() methods declared final, or clone() methods on final classes. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CloneInNonCloneableClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CloneInNonCloneableClass.html index 690e077d4f34..ac652526a039 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CloneInNonCloneableClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CloneInNonCloneableClass.html @@ -3,6 +3,7 @@ This inspection reports classes which override the clone() method, but which do not implement the Cloneable interface. This usually represents a programming error. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CloneableClassInSecureContext.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CloneableClassInSecureContext.html index b90b4d70bb95..e8ff5ef81ba9 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CloneableClassInSecureContext.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CloneableClassInSecureContext.html @@ -4,6 +4,7 @@ This inspection reports classes which may be cloned. A class may be cloned if it supports the Cloneable interface, and its clone() method is not defined to immediately throw an error. Cloneable classes may be dangerous in code intended for secure use. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CloneableImplementsClone.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CloneableImplementsClone.html index 55a9b8c68501..d2482cb4e407 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CloneableImplementsClone.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CloneableImplementsClone.html @@ -3,6 +3,7 @@ This inspection reports classes which implement the Cloneable interface, but which do not override the clone() method. Such classes use the default implementation of clone(), which is often not the desired behavior. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CollectionAddedToSelf.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CollectionAddedToSelf.html index 0f59e3312910..d2c3c81675dc 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CollectionAddedToSelf.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CollectionAddedToSelf.html @@ -4,6 +4,7 @@ This inspection reports any cases where a java.util.Collection or java.util.Map is added as an element of itself. While Bertrand Russell might approve of such a construct, the JVM will likely not, throwing a java.lang.StackOverflowError if hashCode() is ever called on the self-containing collection. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CollectionContainsUrl.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CollectionContainsUrl.html index d7eccf033821..c0ccecc4c50d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CollectionContainsUrl.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CollectionContainsUrl.html @@ -9,6 +9,7 @@ methods of java.net.URL. java.net.URL's equals() and hashCode() method use a DNS lookup, which depending on the availability of the network and the speed of the DNS server can cause significant delays. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CollectionsFieldAccessReplaceableByMethodCall.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CollectionsFieldAccessReplaceableByMethodCall.html index 63deab311baa..53293ea5f018 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CollectionsFieldAccessReplaceableByMethodCall.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CollectionsFieldAccessReplaceableByMethodCall.html @@ -9,6 +9,7 @@ Such method calls prevent "unchecked" warnings by the compiler because the type

This inspection only reports if the project or module is configured to use a language level of 5.0 or higher. +

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CollectionsMustHaveInitialCapacity.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CollectionsMustHaveInitialCapacity.html index 00cb2abcc4fe..4c6f5b551b2f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CollectionsMustHaveInitialCapacity.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CollectionsMustHaveInitialCapacity.html @@ -13,6 +13,7 @@ memory copied when capacity is exceeded. This inspection checks allocations of t

  • java.util.Vector
  • java.util.WeakHashMap +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ComparableImplementedButEqualsNotOverridden.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ComparableImplementedButEqualsNotOverridden.html index 356c58cddd65..073928ff38e1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ComparableImplementedButEqualsNotOverridden.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ComparableImplementedButEqualsNotOverridden.html @@ -7,6 +7,7 @@ the compareTo() implementation. If an object of such a class is added to a collection such as java.util.SortedSet, this collection will violate the contract of java.util.Set, which is defined in terms of equals(). +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ComparatorMethodParameterNotUsed.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ComparatorMethodParameterNotUsed.html index 50cd9c4051e8..87141e5c1bb6 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ComparatorMethodParameterNotUsed.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ComparatorMethodParameterNotUsed.html @@ -3,6 +3,7 @@ This inspection reports any parameters of java.util.Comparator.compare() which are not used. Most likely this is the result of a typing mistake and one parameter is compared with itself or the method is not implemented correctly. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ComparatorNotSerializable.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ComparatorNotSerializable.html index 95792fa79182..bb2843609c5a 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ComparatorNotSerializable.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ComparatorNotSerializable.html @@ -6,6 +6,7 @@ or java.util.TreeSet will become non-Serializable if instantiated with such Comparators. This can result in unexpected and difficult-to-diagnose bugs. Since subclasses of java.lang.Comparator are often stateless, simply marking them Serializable is a small cost to avoid such issues. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CompareToUsesNonFinalVariable.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CompareToUsesNonFinalVariable.html index 7905f7eb71ee..d5c4543afdaf 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CompareToUsesNonFinalVariable.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CompareToUsesNonFinalVariable.html @@ -4,6 +4,7 @@ This inspection reports any implementations of compareTo() which access non-final variables. Such access may result in compareTo() returning different results at different points in an object's lifecycle, which may in turn cause problems when using the standard Collections classes. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ComparisonOfShortAndChar.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ComparisonOfShortAndChar.html index 72693c0722b4..caada42fc583 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ComparisonOfShortAndChar.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ComparisonOfShortAndChar.html @@ -4,6 +4,7 @@ This inspection reports equality comparisons between short and char values. Such comparisons may cause subtle bugs, as short values are signed and char values unsigned. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ComparisonToNaN.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ComparisonToNaN.html index aefc16be7747..623ad1aabbe1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ComparisonToNaN.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ComparisonToNaN.html @@ -5,6 +5,7 @@ This inspection reports any equality or inequality comparisons to Equality comparison to these values is always false. Instead, use the Double.isNaN() of Float.isNaN() methods instead. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ConditionSignal.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ConditionSignal.html index f1b79b54da3b..11d994bdc4dc 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ConditionSignal.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ConditionSignal.html @@ -2,6 +2,7 @@ This inspection reports any calls to java.util.concurrent.locks.signal(). While occasionally useful, in almost all cases signalAll() is a better and safer choice. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ConditionalExpression.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ConditionalExpression.html index 07865bcf73e3..89847d2877a8 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ConditionalExpression.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ConditionalExpression.html @@ -2,6 +2,7 @@ This inspection reports the ternary condition operator. Some coding standards prohibit the use of the condition operator, in favor of if-else statements. +

    Use the checkbox below to ignore simple assignments and returns and thus allow constructs like this:

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ConditionalExpressionWithIdenticalBranches.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ConditionalExpressionWithIdenticalBranches.html
    index 24751a8861d0..ca06ea9fee60 100644
    --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ConditionalExpressionWithIdenticalBranches.html
    +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ConditionalExpressionWithIdenticalBranches.html
    @@ -3,6 +3,7 @@
     This inspection reports conditional expressions
     with identical "then" and "else" branches. Such expressions are almost certainly
     programmer error.
    +
     

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ConfusingElse.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ConfusingElse.html index 4317540c3c13..6a72d085e97d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ConfusingElse.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ConfusingElse.html @@ -5,6 +5,7 @@ when the if statement is followed by other statements and the if b cannot complete normally, for example because it ends with a return statement. In these cases the statements in the else can be moved after the if statement and the else branch removed. +

    Use the checkbox below to also report else branches of if statements whose if branch cannot complete normally and which are not followed by more statements, diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ConfusingFloatingPointLiteral.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ConfusingFloatingPointLiteral.html index 74ff677c7b81..715bec8ccacc 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ConfusingFloatingPointLiteral.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ConfusingFloatingPointLiteral.html @@ -2,6 +2,7 @@ This inspection reports any floating point numbers which do not have a decimal point, numbers before the decimal point, and numbers after the decimal point. Such literals may be confusing, and violate several coding standards. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ConfusingMainMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ConfusingMainMethod.html index 76d166070314..87f7ffbd6a4b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ConfusingMainMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ConfusingMainMethod.html @@ -3,6 +3,7 @@ This inspection reports methods named "main" which do not have signature public static void main(String[]). Such methods may be confusing, as methods named "main" are expected to be application entry points. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ConfusingOctalEscape.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ConfusingOctalEscape.html index d19791c41763..22e58a7e77ae 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ConfusingOctalEscape.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ConfusingOctalEscape.html @@ -2,6 +2,7 @@ This inspection reports any string literals which contain an octal escape sequence immediately followed by a digit. Such strings may be confusing, and are often the result of errors in escape code creation. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ConnectionResource.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ConnectionResource.html index 619607a98a20..55ec147eaaac 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ConnectionResource.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ConnectionResource.html @@ -6,6 +6,7 @@ Applying the results of this inspection without consideration might have negativ This inspection reports any J2ME Connection resource which is not opened in front of a try block and closed in the corresponding finally block. Such resources may be inadvertently leaked if an exception is thrown before the resource is closed. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantAssertCondition.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantAssertCondition.html index a1ce4b0dcf42..b547c66ec572 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantAssertCondition.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantAssertCondition.html @@ -3,6 +3,7 @@ This inspection reports assert statement conditions which are constants. Assert statements with constant conditions will either always fail or always succeed. Such statements can easily be left over after refactoring and are probably a bug. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantConditionalExpression.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantConditionalExpression.html index cf7bec1927ca..2ea6a0190468 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantConditionalExpression.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantConditionalExpression.html @@ -3,6 +3,7 @@ This inspection reports conditional expressions of the form true?result1:result2 or false?result1:result2. These expressions sometimes occur as the result of automatic refactorings, and may obviously be simplified. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantDeclaredInAbstractClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantDeclaredInAbstractClass.html index 98df5ec8d71e..a55deb6498b6 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantDeclaredInAbstractClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantDeclaredInAbstractClass.html @@ -2,6 +2,7 @@ This inspection reports on any constants (i.e. public static final fields) declared in abstract classes. Some coding standards require that constants be declared in interfaces instead. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantDeclaredInInterface.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantDeclaredInInterface.html index 8194dd6065ef..2603d2a7da17 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantDeclaredInInterface.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantDeclaredInInterface.html @@ -2,6 +2,7 @@ This inspection reports on any constants (i.e. public static final fields) declared in interfaces. Some coding standards require that constants be declared in abstract classes instead. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantIfStatement.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantIfStatement.html index fec24382356e..dcbcd492df2c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantIfStatement.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantIfStatement.html @@ -4,6 +4,7 @@ This inspection reports if statements of the form if(true)... or if(false).... These statements sometimes occur due to automatic refactorings, and may obviously be simplified. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantJUnitAssertArgument.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantJUnitAssertArgument.html index 8516788ec411..bfe74026d3c5 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantJUnitAssertArgument.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantJUnitAssertArgument.html @@ -4,6 +4,7 @@ This inspection reports constant arguments to JUnits assertTrue, assertFalse, assertNull and assertNotNull method calls. Calls to these methods with such constant arguments will either always fail or always succeed. Such statements can easily be left over after refactoring and are probably not intended. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantMathCall.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantMathCall.html index 1c4e05e9b60e..462ecd0e79e9 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantMathCall.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantMathCall.html @@ -3,6 +3,7 @@ This inspection reports any calls to java.lang.Math or java.lang.StrictMath methods which can be determined to be simple compile-time constants. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantNamingConvention.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantNamingConvention.html index ce027d3beb2d..b66b6bcf9819 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantNamingConvention.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantNamingConvention.html @@ -2,6 +2,7 @@ This inspection reports any constants whose names are either too short, too long, or do not follow the specified regular expression pattern. Constants are fields declared static final. +

    Use the fields provided below to specify minimum length, maximum length and regular expression expected for constant names (Regular expressions are in standard java.util.regex format). Use the diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantOnLHSOfComparison.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantOnLHSOfComparison.html index 39efbfb95a55..8478695b3177 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantOnLHSOfComparison.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantOnLHSOfComparison.html @@ -2,6 +2,7 @@ This inspection reports on comparison operations with constant values on their left-hand side. Some coding conventions specify that constants should be on the right-hand side of comparisons. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantOnRHSOfComparison.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantOnRHSOfComparison.html index 8f9d8dde2fea..f08b010e8e9f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantOnRHSOfComparison.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantOnRHSOfComparison.html @@ -2,6 +2,7 @@ This inspection reports on comparison operations with constant values on their right-hand side. Some coding conventions specify that constants should be on the left-hand side of comparisons. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantStringIntern.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantStringIntern.html index 5984cc81fb48..b66373d5521f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantStringIntern.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantStringIntern.html @@ -3,6 +3,7 @@ This inspection reports on any call to String.intern() on a compile-time constant string. Per the Java Language Specification, compile-time constant strings are automatically interned, making the call to String.intern() redundant. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantValueVariableUse.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantValueVariableUse.html index 4d071c06b455..9ef722d22c40 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantValueVariableUse.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstantValueVariableUse.html @@ -6,6 +6,7 @@ is the case if the (read) use of the variable is surrounded by an statement with an == condition which compares the variable with a constant. In such a case the use of a variable which is known to be constant can be replaced with the actual constant. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstructorCount.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstructorCount.html index b6d276deb3b2..f3281d8715de 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ConstructorCount.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ConstructorCount.html @@ -3,6 +3,7 @@ This inspection reports class with too many constructors. Classes with too many constructors are prone to initialization errors, and may often be better modeled as multiple subclasses. +

    Use the field provided below to specify the maximum acceptable number of constructors a class might have.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ContinueOrBreakFromFinallyBlock.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ContinueOrBreakFromFinallyBlock.html index 585e158ae97b..0a8cc625caf9 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ContinueOrBreakFromFinallyBlock.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ContinueOrBreakFromFinallyBlock.html @@ -4,6 +4,7 @@ This inspection reports break or continue statements inside of finally blocks. While occasionally intended, such statements are very confusing, may mask exceptions thrown, and tremendously complicate debugging. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ContinueStatement.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ContinueStatement.html index d9312d7e09c2..70aeb61b3b43 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ContinueStatement.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ContinueStatement.html @@ -2,6 +2,7 @@ This inspection reports continue statements. continue statements complicate refactoring, and can be confusing. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ContinueStatementWithLabel.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ContinueStatementWithLabel.html index a07824d704fc..44176177e4bb 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ContinueStatementWithLabel.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ContinueStatementWithLabel.html @@ -2,6 +2,7 @@ This inspection reports continue statements with labels. Labeled continue statements complicate refactoring, and can be confusing. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ControlFlowStatementWithoutBraces.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ControlFlowStatementWithoutBraces.html index bb3bfe8ac23b..74cc8f8551de 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ControlFlowStatementWithoutBraces.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ControlFlowStatementWithoutBraces.html @@ -4,6 +4,7 @@ This inspection reports any if, while or for statements without braces. Braces make the code easier to read and help prevent errors when modifying the code. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CovariantCompareTo.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CovariantCompareTo.html index d34053578c9c..08dedc38a056 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CovariantCompareTo.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CovariantCompareTo.html @@ -3,6 +3,7 @@ This inspection reports a class having a compareTo() method taking an argument other than java.lang.Object, if the class does not have a compareTo() method which does take java.lang.Object as its argument. Normally, this is a mistake. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CovariantEquals.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CovariantEquals.html index 49b4171b937d..7312e120a52c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CovariantEquals.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CovariantEquals.html @@ -3,6 +3,7 @@ This inspection reports a class having a equals() method taking an argument other than java.lang.Object, if the class does not have a equals() method which does take java.lang.Object as its argument. Normally, this is a mistake. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CustomClassloader.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CustomClassloader.html index 4409ff4dec6c..455da50af1b1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CustomClassloader.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CustomClassloader.html @@ -3,6 +3,7 @@ This inspection reports any user-defined subclasses of java.lang.ClassLoader. While not necessarily representing a security hole, such classes should be thoroughly and professionally inspected for possible security issues. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CustomSecurityManager.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CustomSecurityManager.html index d73211213431..d64c0b9bf30f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CustomSecurityManager.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CustomSecurityManager.html @@ -3,6 +3,7 @@ This inspection reports any user-defined subclasses of java.lang.SecurityManager. While not necessarily representing a security hole, such classes should be thoroughly and professionally inspected for possible security issues. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CyclicClassDependency.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CyclicClassDependency.html index dbb9780b5108..08835b94097f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CyclicClassDependency.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CyclicClassDependency.html @@ -3,6 +3,7 @@ This global inspection reports any classes which are mutually or cyclically dependent on other classes. Such cyclic dependencies make for fragile code and high maintenance costs. Since this inspection requires global code analysis, it is only available in batch inspection mode. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CyclicPackageDependency.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CyclicPackageDependency.html index b2d18bc7538b..3cd47e9d1afe 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CyclicPackageDependency.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CyclicPackageDependency.html @@ -3,6 +3,7 @@ This global inspection reports any packages which are mutually or cyclically dependent on other packages. Such cyclic dependencies make for fragile code and high maintenance costs. Since this inspection requires global code analysis, it is only available in batch inspection mode. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/CyclomaticComplexity.html b/plugins/InspectionGadgets/src/inspectionDescriptions/CyclomaticComplexity.html index f3e747c61a90..3714b0d4b19e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/CyclomaticComplexity.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/CyclomaticComplexity.html @@ -3,6 +3,7 @@ This inspection reports methods that have too high a cyclomatic complexity. Cyclomatic complexity is basically a measurement of the number of branching points in a method. Methods with too high a cyclomatic complexity may be confusing and difficult to test. +

    Use the field provided below to specify the maximum acceptable cyclomatic complexity a method might have.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/DateToString.html b/plugins/InspectionGadgets/src/inspectionDescriptions/DateToString.html index 26bef63346c6..9d97af092f49 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/DateToString.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/DateToString.html @@ -2,6 +2,7 @@ This inspection reports any call of toString() on java.util.Date objects. Such calls are usually incorrect in an internationalized environment. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/DeclareCollectionAsInterface.html b/plugins/InspectionGadgets/src/inspectionDescriptions/DeclareCollectionAsInterface.html index 0e23a202e170..2b5bd90b766e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/DeclareCollectionAsInterface.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/DeclareCollectionAsInterface.html @@ -2,6 +2,7 @@ This inspection reports on declarations of Collection variables made by using the collection class as the type, rather than an appropriate interface. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/DefaultNotLastCaseInSwitch.html b/plugins/InspectionGadgets/src/inspectionDescriptions/DefaultNotLastCaseInSwitch.html index 5c3c0b6073c4..9fe1cda2543d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/DefaultNotLastCaseInSwitch.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/DefaultNotLastCaseInSwitch.html @@ -2,6 +2,7 @@ This inspection reports switch statements where the default case comes before some other case. This construct is unnecessarily confusing. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/DeserializableClassInSecureContext.html b/plugins/InspectionGadgets/src/inspectionDescriptions/DeserializableClassInSecureContext.html index f2312103759d..d1c389ff0fb1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/DeserializableClassInSecureContext.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/DeserializableClassInSecureContext.html @@ -4,6 +4,7 @@ This inspection reports classes which may be deserialized. A class may be deserialized if it supports the Serializable interface, and its readObject() method is not defined to immediately throw an error. Deserializable classes may be dangerous in code intended for secure use. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/DesignForExtension.html b/plugins/InspectionGadgets/src/inspectionDescriptions/DesignForExtension.html index e0decbdce087..26d77163c4bd 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/DesignForExtension.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/DesignForExtension.html @@ -10,6 +10,7 @@ execution of code in the superclass.

    This inspection is intended for code to be used in secure environments, and is probably not appropriate for less restrictive environments. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/DisjointPackage.html b/plugins/InspectionGadgets/src/inspectionDescriptions/DisjointPackage.html index 3c348312c1dd..30695494abf8 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/DisjointPackage.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/DisjointPackage.html @@ -3,6 +3,7 @@ This inspection reports any packages whose classes can be separated into disjoint, mutually independent subsets. Such disjoint packages are a symptom of ad-hoc packaging, and may indicate a lack of conceptual cohesion. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/DivideByZero.html b/plugins/InspectionGadgets/src/inspectionDescriptions/DivideByZero.html index dbb8e5db803b..c174eb82932a 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/DivideByZero.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/DivideByZero.html @@ -1,6 +1,7 @@ This inspection reports division by zero or remainder by zero. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/DollarSignInName.html b/plugins/InspectionGadgets/src/inspectionDescriptions/DollarSignInName.html index 2cc61d8dafa4..47f393c4c7ae 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/DollarSignInName.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/DollarSignInName.html @@ -2,6 +2,7 @@ This inspection reports identifers containing dollar signs ('$'). While such identifiers are legal Java, their use outside of generated java code is strongly discouraged. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/DoubleCheckedLocking.html b/plugins/InspectionGadgets/src/inspectionDescriptions/DoubleCheckedLocking.html index fd11ad3979c1..5659ee383d39 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/DoubleCheckedLocking.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/DoubleCheckedLocking.html @@ -4,6 +4,7 @@ This inspection reports the double-checked locking construct. For a discussion of double-checked locking and why it is unsafe, see http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html +

    Use the checkbox below to ignore double-checked locking on volatile fields. Using a volatile field for double-checked locking works correctly on virtual machines which diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/DoubleLiteralMayBeFloatLiteral.html b/plugins/InspectionGadgets/src/inspectionDescriptions/DoubleLiteralMayBeFloatLiteral.html index 10b88fa6b740..59a4362a69eb 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/DoubleLiteralMayBeFloatLiteral.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/DoubleLiteralMayBeFloatLiteral.html @@ -4,6 +4,7 @@ This inspection reports double literal expressions which are immediately cast to float. Such literal expressions can be replaced with the equivalent float literal. +

    New in 10.0.2, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/DoubleNegation.html b/plugins/InspectionGadgets/src/inspectionDescriptions/DoubleNegation.html index 39f2cf7bb831..c1213bb6b190 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/DoubleNegation.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/DoubleNegation.html @@ -4,6 +4,7 @@ This inspection reports double negation.

    For example:

    if (!!functionCall())
    +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/DriverManagerGetConnection.html b/plugins/InspectionGadgets/src/inspectionDescriptions/DriverManagerGetConnection.html index d9d0292d3b1a..878988304c00 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/DriverManagerGetConnection.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/DriverManagerGetConnection.html @@ -4,6 +4,7 @@ This inspection reports any uses to javax.sql.DriverManager to acquire a JDBC connection. The javax.sql.DriverManager has been superseded by javax.sql.Datasource, which allows for connection pooling and other optimizations. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/DuplicateBooleanBranch.html b/plugins/InspectionGadgets/src/inspectionDescriptions/DuplicateBooleanBranch.html index 88a29e02acdf..6f9f607a02a3 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/DuplicateBooleanBranch.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/DuplicateBooleanBranch.html @@ -3,6 +3,7 @@ This inspection reports duplicated branches in && or || expressions. Such constructs almost always represents a typo or cut-and-paste error. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/DuplicateCondition.html b/plugins/InspectionGadgets/src/inspectionDescriptions/DuplicateCondition.html index 1c04d07a5c5d..0eddc9d51162 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/DuplicateCondition.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/DuplicateCondition.html @@ -3,6 +3,7 @@ This inspection reports on any duplicate conditions among different branches of an if statement. While it may rarely be the desired semantics, duplicate conditions usually represent programmer oversight. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/DynamicRegexReplaceableByCompiledPattern.html b/plugins/InspectionGadgets/src/inspectionDescriptions/DynamicRegexReplaceableByCompiledPattern.html index 1272f17b2569..0d35c30d60fb 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/DynamicRegexReplaceableByCompiledPattern.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/DynamicRegexReplaceableByCompiledPattern.html @@ -5,6 +5,7 @@ This inspection reports calls to the regular expression methods of Such calls may be profitably replaced with a private static final Pattern field so that the regular expression does not have to be compiled each time it is used. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ElementOnlyUsedFromTestCode.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ElementOnlyUsedFromTestCode.html index 4bb83235c869..7aabf36560e5 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ElementOnlyUsedFromTestCode.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ElementOnlyUsedFromTestCode.html @@ -2,6 +2,7 @@ This global inspection reports classes, methods or fields which are only used from test code. Since this inspection requires global code analysis, it is only available in batch inspection mode. +

    New in 11, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyCatchBlock.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyCatchBlock.html index cc1163c49c72..f81294a3d54d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyCatchBlock.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyCatchBlock.html @@ -4,6 +4,7 @@ This inspection reports empty catch blocks. While occasionally intended, empty catch blocks can make debugging extremely difficult.

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

    Use the controls below to indicate whether catch blocks containing only comments, empty catch blocks in JUnit tests should be reported and whether to ignore empty diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyDirectory.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyDirectory.html index a76300ef8ea9..04fb7dec0f63 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyDirectory.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyDirectory.html @@ -1,6 +1,7 @@ This inspection reports empty directories. +

    Use the checkbox below to have this inspection only report directories under source roots.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyFinallyBlock.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyFinallyBlock.html index 09ca17225ae2..9899406f5efd 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyFinallyBlock.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyFinallyBlock.html @@ -2,6 +2,7 @@ This inspection reports empty finally blocks. Empty finally blocks usually indicate coding errors. +

    At present, this inspection is disabled in JSP files.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyInitializer.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyInitializer.html index aca206b9dae5..a290c2c01a96 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyInitializer.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyInitializer.html @@ -1,6 +1,7 @@ This inspection reports empty class initializer blocks. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyStatementBody.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyStatementBody.html index 99d44cfc7bc9..a9c245b9cf1c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyStatementBody.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyStatementBody.html @@ -3,6 +3,7 @@ This inspection reports if, while, do or for statements 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.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EmptySynchronizedStatement.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EmptySynchronizedStatement.html index 53c3cef9d2c6..d62859695715 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/EmptySynchronizedStatement.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/EmptySynchronizedStatement.html @@ -3,6 +3,7 @@ This inspection reports synchronized statements having empty bodies. While theoretically this may be the semantics intended, this construction is confusing, and often the result of a typo. +

    At present, this inspection is disabled in JSP files.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyTryBlock.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyTryBlock.html index 83d871a9cfee..6e6c628df7d4 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyTryBlock.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/EmptyTryBlock.html @@ -1,6 +1,7 @@ This inspection reports empty try blocks. +

    At present, this inspection is disabled in JSP files.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EnumAsName.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EnumAsName.html index ae043583c1cb..b991c879c0dd 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/EnumAsName.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/EnumAsName.html @@ -3,6 +3,7 @@ This inspection reports variables, methods, or classes named enum. Such names are legal under Java 1.4 or earlier JVMs, but will cause problems under Java 5.0 or later. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EnumClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EnumClass.html index cb4b6074255d..c1de52c30467 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/EnumClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/EnumClass.html @@ -2,6 +2,7 @@ This inspection reports enum classes. Such statements are not supported under Java 1.4 or earlier JVMs. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EnumSwitchStatementWhichMissesCases.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EnumSwitchStatementWhichMissesCases.html index 8cbaa9bd5cbb..24aed00e8ea2 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/EnumSwitchStatementWhichMissesCases.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/EnumSwitchStatementWhichMissesCases.html @@ -2,6 +2,7 @@ This inspection reports switch statements over enumerated types which do not include all of the enumerated type's elements as cases. +

    Use the check box below to let this inspection ignore switch statements which include a default branch. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EnumeratedClassNamingConvention.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EnumeratedClassNamingConvention.html index d9c3f40f72bb..42cbc8329b49 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/EnumeratedClassNamingConvention.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/EnumeratedClassNamingConvention.html @@ -2,6 +2,7 @@ This inspection reports enumerated classes whose names are either too short, too long, or do not follow the specified regular expression pattern. +

    Use the fields provided below to specify minimum length, maximum length and regular expression expected for enumerated class names. (Regular expressions are in standard java.util.regex format.) diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EnumeratedConstantNamingConvention.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EnumeratedConstantNamingConvention.html index 0c2bc7021dcb..139df04ce1c0 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/EnumeratedConstantNamingConvention.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/EnumeratedConstantNamingConvention.html @@ -2,6 +2,7 @@ This inspection reports enumerated constants whose names are either too short, too long, or do not follow the specified regular expression pattern. +

    Use the fields provided below to specify minimum length, maximum length and regular expression expected for enumerated constant names. (Regular expressions are in standard java.util.regex format.) diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EnumerationCanBeIteration.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EnumerationCanBeIteration.html index ee684f862147..8f31645fc67d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/EnumerationCanBeIteration.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/EnumerationCanBeIteration.html @@ -4,6 +4,7 @@ This inspection reports Enumeration methods used, which can be replaced equivalent Iterator constructs. Iterators are part of the Java Collection Framework, which has been available since Java 1.2. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsBetweenInconvertibleTypes.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsBetweenInconvertibleTypes.html index 874f5db04ece..0c4432f18fa3 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsBetweenInconvertibleTypes.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsBetweenInconvertibleTypes.html @@ -3,6 +3,7 @@ This inspection reports calls to .equals() where the target and argument are of incompatible types. While such a call might theoretically be useful, most likely it represents a bug. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsCalledOnEnumConstant.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsCalledOnEnumConstant.html index 57b1de8214ce..95690553f20f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsCalledOnEnumConstant.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsCalledOnEnumConstant.html @@ -5,6 +5,7 @@ This inspection reports calls to equals() on an identity comparison (==) because two Enum constants are equal only when they have the same identity. +

    New in 8.1, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsHashCodeCalledOnUrl.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsHashCodeCalledOnUrl.html index 03d5d491acc0..faeba5bdcca3 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsHashCodeCalledOnUrl.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsHashCodeCalledOnUrl.html @@ -7,6 +7,7 @@ problems because those methods uses a DNS lookup to determine the equality of two java.net.URL objects. Depending on the availability of the network and the speed of the DNS server, this can cause significant delays. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsUsesNonFinalVariable.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsUsesNonFinalVariable.html index c3c14c7d97ac..08cb0838bfda 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsUsesNonFinalVariable.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsUsesNonFinalVariable.html @@ -4,6 +4,7 @@ This inspection reports any implementations of equals() which access non-final variables. Such access may result in equals() returning different results at different points in an object's lifecycle, which may in turn cause problems when using the standard Collections classes. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsWhichDoesntCheckParameterClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsWhichDoesntCheckParameterClass.html index f451c60c1616..ce7608c0585a 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsWhichDoesntCheckParameterClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsWhichDoesntCheckParameterClass.html @@ -3,6 +3,7 @@ This inspection reports equals() methods which do not check the type of their parameter. Failure to check the type of the parameter in the equals() method may result in latent errors if the object is later used in an untyped collection. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ErrorRethrown.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ErrorRethrown.html index ca123561dbd7..44885df040e4 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ErrorRethrown.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ErrorRethrown.html @@ -4,6 +4,7 @@ This inspection reports try statements which catch java.lang.Error or any subclass and which do not rethrow the error. Statements which catch java.lang.ThreadDeath are not reported by this inspection. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ExceptionFromCatchWhichDoesntWrap.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ExceptionFromCatchWhichDoesntWrap.html index 52c377f46978..46d386754538 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ExceptionFromCatchWhichDoesntWrap.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ExceptionFromCatchWhichDoesntWrap.html @@ -5,6 +5,7 @@ from inside catch blocks, which do not "wrap" the caught exception. It is considered good practice when throwing an exception in response to an exception to wrap the initial exception, so that valuable context information such as stack frames and line numbers are not lost. +

    Use the first checkbox below to indicate if the inspection should ignore exceptions which receive the result of a method call on the original exception, such as getMessage(), diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ExceptionNameDoesntEndWithException.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ExceptionNameDoesntEndWithException.html index dfabd94e0cfc..506b77fc78c2 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ExceptionNameDoesntEndWithException.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ExceptionNameDoesntEndWithException.html @@ -1,6 +1,7 @@ This inspection reports exception classes whose names don't end with 'Exception'. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ExpectedExceptionNeverThrown.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ExpectedExceptionNeverThrown.html index 3d979ec5b2d7..47aefcfa28af 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ExpectedExceptionNeverThrown.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ExpectedExceptionNeverThrown.html @@ -2,6 +2,7 @@ This inspection reports checked exceptions expected by a JUnit 4 test method, which are never thrown inside the method body. +

    New in 10, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ExtendsAnnotation.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ExtendsAnnotation.html index 23e7d9264e70..90cf5aef0abd 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ExtendsAnnotation.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ExtendsAnnotation.html @@ -3,6 +3,7 @@ This inspection reports any classes declared as implementing or extending an annotation interface. While it is legal to extend an annotation interface, it is nearly meaningless, and discouraged. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ExtendsConcreteCollection.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ExtendsConcreteCollection.html index b213eed47291..f1a5ca3ba917 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ExtendsConcreteCollection.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ExtendsConcreteCollection.html @@ -5,6 +5,7 @@ This inspection reports any clases which extend concrete classes of type java.util.Map. Subclassing collection types is a common practice of novice object-oriented developers, but is considerably more brittle than delegating collection calls. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ExtendsObject.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ExtendsObject.html index 2eba274c811a..5231ff2cd268 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ExtendsObject.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ExtendsObject.html @@ -1,6 +1,7 @@ This inspection reports any classes explicitly declared to extend java.lang.Object. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ExtendsThread.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ExtendsThread.html index efd336488e03..bb8a703d553d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ExtendsThread.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ExtendsThread.html @@ -4,6 +4,7 @@ This inspection reports any clases which extend java.lang.Thread. It is usually thought better practice to delegate to rather than extend java.lang.Thread, so that a thread creator may exert better control over the thread's behavior, and to better localize all concurrency related operations. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ExtendsUtilityClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ExtendsUtilityClass.html index f144ac16f6f6..c126919c4a50 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ExtendsUtilityClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ExtendsUtilityClass.html @@ -4,6 +4,7 @@ This inspection reports any classes explicitly declared to extend a utility clas have all fields and methods declared static. Extending a utility class also allows inadvertent object instantiation of the utility class, because to allow extension the constructor can not be made private. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ExternalizableWithSerializationMethods.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ExternalizableWithSerializationMethods.html index 60bb62791d67..b097f6ab8fcb 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ExternalizableWithSerializationMethods.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ExternalizableWithSerializationMethods.html @@ -3,6 +3,7 @@ This inspection reports Externalizable classes which define readObject() or writeObject() methods. These methods are not called for serialization of Externalizable objects. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ExternalizableWithoutPublicNoArgConstructor.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ExternalizableWithoutPublicNoArgConstructor.html index 96d0db829104..615f610b91cc 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ExternalizableWithoutPublicNoArgConstructor.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ExternalizableWithoutPublicNoArgConstructor.html @@ -3,6 +3,7 @@ This inspection reports a Externalizable classes without a public no-argument constructor. When an Externalizable object is reconstructed, an instance is created using the public no-arg constructor before the readExternal method called. If a public no-arg constructor is not present a java.io.InvalidClassException will be thrown at runtime. +

    New in 12, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/FallthruInSwitchStatement.html b/plugins/InspectionGadgets/src/inspectionDescriptions/FallthruInSwitchStatement.html index 08215ebfcf8a..2ddf8a99d871 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/FallthruInSwitchStatement.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/FallthruInSwitchStatement.html @@ -5,6 +5,7 @@ This inspection reports 'fallthrough' in a switch statement. to transfer control before the next switch label. In that case, control 'falls through' to the statements after that switch label, even though the switch expression does not equal the value of the fallen-through label. While occasionally intended, this construction is confusing, and is often the result of a typo. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/FeatureEnvy.html b/plugins/InspectionGadgets/src/inspectionDescriptions/FeatureEnvy.html index 952f773b6bb8..1db0476a0940 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/FeatureEnvy.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/FeatureEnvy.html @@ -5,6 +5,7 @@ envy is defined as occurring when a method calls methods on another class three or more times. Calls to library classes, parent classes, contained or containing classes are not counted for purposes of this inspection. Feature envy is often an indication that functionality is located in the wrong class. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/FieldAccessedSynchronizedAndUnsynchronized.html b/plugins/InspectionGadgets/src/inspectionDescriptions/FieldAccessedSynchronizedAndUnsynchronized.html index 10274d0b171d..806bd3ffc939 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/FieldAccessedSynchronizedAndUnsynchronized.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/FieldAccessedSynchronizedAndUnsynchronized.html @@ -4,6 +4,7 @@ This inspection reports non-final fields which are accessed in both synchronized unsynchronized contexts. Volatile fields and accesses in constructors and initializers are ignored by this inspection. Such "partially synchronized" access is often the result of a coding oversight, and may result in unexpectedly inconsistent data structures. +

    Use the checkbox below to specify if simple getters and setters are counted as accesses too.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/FieldCanBeMovedToSubclass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/FieldCanBeMovedToSubclass.html index b230641d3876..608c82b0c23e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/FieldCanBeMovedToSubclass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/FieldCanBeMovedToSubclass.html @@ -2,6 +2,7 @@ This global inspection reports any instance fields which can be moved to a subclass. Since this inspection requires global code analysis, it is only available in batch inspection mode. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/FieldCount.html b/plugins/InspectionGadgets/src/inspectionDescriptions/FieldCount.html index f5462f0f1989..55ac08810201 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/FieldCount.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/FieldCount.html @@ -3,6 +3,7 @@ This inspection reports class with too many fields. Classes with a large number of fields are often trying to 'do too much', and may need to be refactored into multiple smaller classes. +

    Use the controls below to specify the maximum acceptable number of fields a class might have, and to indicate whether constant fields count toward this number. Per default this inspection only counts diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/FieldHasSetterButNoGetter.html b/plugins/InspectionGadgets/src/inspectionDescriptions/FieldHasSetterButNoGetter.html index d0300121bfd3..af8c68453265 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/FieldHasSetterButNoGetter.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/FieldHasSetterButNoGetter.html @@ -3,6 +3,7 @@ This inspection reports any fields which have a "setter" method but no "getter" method. While within the Java beans spec, such fields may be unnecessarily difficult to work with in certain bean containers. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/FieldHidesSuperclassField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/FieldHidesSuperclassField.html index 9e313497e526..5045a149d8fb 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/FieldHidesSuperclassField.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/FieldHidesSuperclassField.html @@ -2,6 +2,7 @@ This inspection reports fields with the same name as a field in an ancestor class. Such field names may be confusing, and can be bug-prone. +

    Use the checkbox below the indicate whether this inspection should report all name clashes, or only clashes with fields which are visible from the subclass. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/FieldMayBeFinal.html b/plugins/InspectionGadgets/src/inspectionDescriptions/FieldMayBeFinal.html index dbaf9f6cf3d6..475039e88c30 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/FieldMayBeFinal.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/FieldMayBeFinal.html @@ -4,6 +4,7 @@ This inspection reports any fields which may safely be made final. A static field may be final if it is initialized in its declaration or in one static class initializer, but not both. A non-static field may be final if it is initialized in its declaration or in one non-static class initializer or in all constructors. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/FieldMayBeStatic.html b/plugins/InspectionGadgets/src/inspectionDescriptions/FieldMayBeStatic.html index c9b433223f22..033bfbec8b93 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/FieldMayBeStatic.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/FieldMayBeStatic.html @@ -2,6 +2,7 @@ This inspection reports any instance variables which may safely be made static. A field may be static if it is declared final, and is initialized with a constant. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/FieldRepeatedlyAccessed.html b/plugins/InspectionGadgets/src/inspectionDescriptions/FieldRepeatedlyAccessed.html index dc2961cea10d..5b479471108e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/FieldRepeatedlyAccessed.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/FieldRepeatedlyAccessed.html @@ -6,6 +6,7 @@ Applying the results of this inspection without consideration might have negativ This inspection reports fields which are accessed three or more times by a given method, or which are accessed in a loop. While such field access may be logically correct, it is often more performant to replace such accesses with local variables, copying the fields to a temporary local and copying back if necessary. +

    Use the checkbox below to ignore final fields being repeatedly accessed, as many compilers and JVMs can optimize that case without explicit creation of a temporary local variable. Constant fields are always ignored by this inspection. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/FinalClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/FinalClass.html index 330dc81d2a22..54059dea46c9 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/FinalClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/FinalClass.html @@ -2,6 +2,7 @@ This inspection reports classes being declared final. Some coding standards discourage final classes. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/FinalMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/FinalMethod.html index 01effd407f76..e2b776382131 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/FinalMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/FinalMethod.html @@ -2,6 +2,7 @@ This inspection reports methods being declared final. Some coding standards discourage final methods. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/FinalMethodInFinalClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/FinalMethodInFinalClass.html index c1eba485fc14..f014731268a4 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/FinalMethodInFinalClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/FinalMethodInFinalClass.html @@ -2,6 +2,7 @@ This inspection reports methods being declared final in classes that are declared final. This is unnecessary, and may be confusing. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/FinalPrivateMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/FinalPrivateMethod.html index 8e9e50482b5f..08a69e5ab5b2 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/FinalPrivateMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/FinalPrivateMethod.html @@ -4,6 +4,7 @@ This inspection reports methods declared final and private. As private methods cannot be meaningfully overridden, declaring them final is redundant. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/FinalStaticMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/FinalStaticMethod.html index d78ba0deaec8..51d3f6e5f74f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/FinalStaticMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/FinalStaticMethod.html @@ -6,6 +6,7 @@ accessed via the super class, making a final declaration not very necessa Declaring a static method final does prevent subclasses from defining a static method with the same signature. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/Finalize.html b/plugins/InspectionGadgets/src/inspectionDescriptions/Finalize.html index 1c8a8b55d36e..fd037620112c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/Finalize.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/Finalize.html @@ -4,6 +4,7 @@ This inspection reports any implementations of a finalize() method. For performance reasons or due to inability to guarantee that finalize() will ever be called, some coding standards prohibit its use. +

    Use the checkbox below to ignore finalize() implementations with an empty method body or a body containing only if statements which have a condition which diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/FinalizeCallsSuperFinalize.html b/plugins/InspectionGadgets/src/inspectionDescriptions/FinalizeCallsSuperFinalize.html index 9f8dd35570be..90899bea2aa1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/FinalizeCallsSuperFinalize.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/FinalizeCallsSuperFinalize.html @@ -3,6 +3,7 @@ This inspection reports any implementations of the Object.finalize() method which do not call super.finalize(). Failing to call super.finalize() may result in objects failing to properly free any resources held or do other cleanup activities. +

    Use the checkboxes below to ignore direct subclasses of java.lang.Object or to ignore finalize() implementations with an empty diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/FinalizeNotProtected.html b/plugins/InspectionGadgets/src/inspectionDescriptions/FinalizeNotProtected.html index ed10bb9e327b..bd5d83809f54 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/FinalizeNotProtected.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/FinalizeNotProtected.html @@ -3,6 +3,7 @@ This inspection reports any implementations of the Object.finalize() method which are not declared protected. finalize() should be declare protected, to prevent it from being explicitly invoked by other classes. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/FinallyBlockCannotCompleteNormally.html b/plugins/InspectionGadgets/src/inspectionDescriptions/FinallyBlockCannotCompleteNormally.html index 23bfddaf5fc2..9ca990f848cb 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/FinallyBlockCannotCompleteNormally.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/FinallyBlockCannotCompleteNormally.html @@ -2,6 +2,7 @@ This inspection reports finally blocks which can not complete normally. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/FloatingPointEquality.html b/plugins/InspectionGadgets/src/inspectionDescriptions/FloatingPointEquality.html index 870a09c1d34b..43ea70eb4275 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/FloatingPointEquality.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/FloatingPointEquality.html @@ -5,6 +5,7 @@ being compared with == or !=. Floating point values are inherently inaccurate, and comparing them for exact equality is almost never the desired semantics. This inspection ignores comparisons with zero literals. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ForCanBeForeach.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ForCanBeForeach.html index 886fe67fc8f5..4563b819f470 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ForCanBeForeach.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ForCanBeForeach.html @@ -3,6 +3,7 @@ This inspection reports for loops which iterate over collections or arrays, and can be replaced with the "for each" iteration syntax, available in Java 5 and newer. +

    Use the first checkbox below to find loops involving list.get(index) calls. These loops generally can be replaced with the foreach loops, unless they modify underlying list in the process, e.g. by calling list.remove(index). diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ForLoopReplaceableByWhile.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ForLoopReplaceableByWhile.html index 2a4e16bda97d..4650c95513fe 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ForLoopReplaceableByWhile.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ForLoopReplaceableByWhile.html @@ -3,6 +3,7 @@ This inspection reports for loops which contain neither initialization or update components, and can thus be replaced by simpler while statements. +

    Use the checkbox below if you wish this inspection to ignore for loops with trivial or non-existent conditions.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ForLoopThatDoesntUseLoopVariable.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ForLoopThatDoesntUseLoopVariable.html index 4e6dd35f7bc5..84ba3e9169f1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ForLoopThatDoesntUseLoopVariable.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ForLoopThatDoesntUseLoopVariable.html @@ -2,6 +2,7 @@ This inspection reports for loops where the condition or update does not use the for loop variable. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ForLoopWithMissingComponent.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ForLoopWithMissingComponent.html index fbaa4ec2ac6b..a69d51e4ba66 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ForLoopWithMissingComponent.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ForLoopWithMissingComponent.html @@ -3,6 +3,7 @@ This inspection reports for loops that lack initialization, condition, or update clauses. Some coding styles prohibit such loops. +

    Use the checkbox below to let this inspection ignore loops which use an iterator. This is a standard way to iterate over a collection, in which the diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ForeachStatement.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ForeachStatement.html index 0bca40a2ee01..040d6a73f734 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ForeachStatement.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ForeachStatement.html @@ -2,6 +2,7 @@ This inspection reports the Java 5 for statement syntax. Such for statements are not supported under Java 1.4 and older. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/HardcodedFileSeparators.html b/plugins/InspectionGadgets/src/inspectionDescriptions/HardcodedFileSeparators.html index 06fa856c8f8b..c1f86cc7d6c3 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/HardcodedFileSeparators.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/HardcodedFileSeparators.html @@ -8,6 +8,7 @@ strings representing a java.util.TimeZone ID, strings that are a valid re

    Normally, usage of the example/* MIME media type outside of an example (e.g. in a Content-Type header) is an error. Use the checkbox below to include example/* in the set of recognized media types. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/HardcodedLineSeparators.html b/plugins/InspectionGadgets/src/inspectionDescriptions/HardcodedLineSeparators.html index 43e698716ad7..39ed41aad409 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/HardcodedLineSeparators.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/HardcodedLineSeparators.html @@ -2,6 +2,7 @@ This inspection reports the newline (\n) or return (\r) characters in a string or character literal. These characters are commonly used as line separators, and portability may suffer they are hardcoded. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/HashCodeUsesNonFinalVariable.html b/plugins/InspectionGadgets/src/inspectionDescriptions/HashCodeUsesNonFinalVariable.html index 6b8b69b390f7..93cd3d1dddd4 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/HashCodeUsesNonFinalVariable.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/HashCodeUsesNonFinalVariable.html @@ -4,6 +4,7 @@ This inspection reports any implementations of hashcode() which access non-final variables. Such access may result in hashcode() returning different values at different points in an object's lifecycle, which may in turn cause problems when using the standard Collections classes. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/HibernateResource.html b/plugins/InspectionGadgets/src/inspectionDescriptions/HibernateResource.html index b5602f336725..18d36b408d7d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/HibernateResource.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/HibernateResource.html @@ -5,6 +5,7 @@ This inspection reports any Hibernate resource which is not opened in a tryfinally block. Such resources may be inadvertently leaked if an exception is thrown before the resource is closed. Hibernate resources reported by this inspection include org.hibernate.Session. +

    Use the checkbox below to specify if a Hibernate resource is allowed to be opened inside a try block. This style is less desirable because it is more verbose than opening a resource diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/HtmlTagCanBeJavadocTag.html b/plugins/InspectionGadgets/src/inspectionDescriptions/HtmlTagCanBeJavadocTag.html index 90cb3d6b696a..d8983bf0ac24 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/HtmlTagCanBeJavadocTag.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/HtmlTagCanBeJavadocTag.html @@ -3,6 +3,7 @@ This inspection reports use of <code> tags in Javadoc comments. Since JDK1.5 these constructs may be replaced with {@code ...} constructs. This allows the use of angle brackets (<>) inside the comment, instead of HTML character entities. +

    New in 10.5, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/IOResource.html b/plugins/InspectionGadgets/src/inspectionDescriptions/IOResource.html index 5c2af355742f..4c0c383c9a15 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/IOResource.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/IOResource.html @@ -9,6 +9,7 @@ by this inspection include java.io.InputStream, java.io.Writer and java.io.RandomAccessFile. I/O resources which are wrapped by other I/O resources are not reported, as the wrapped resource will be closed by the wrapping resource. +

    Use the table below to specify which I/O resources should be ignored by this inspection. Specify I/O resource classes here which do not need to be closed. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/IfCanBeSwitch.html b/plugins/InspectionGadgets/src/inspectionDescriptions/IfCanBeSwitch.html index 8a4c71f2c14c..61f6cb6c3bdd 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/IfCanBeSwitch.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/IfCanBeSwitch.html @@ -3,6 +3,7 @@ This inspection reports any if statements with which can be replaced by a switch statement. This inspection will automatically suggest string switches when the project language level is jdk 1.7 or higher. +

    Use the text field below to indicate the minimum number of case branches the resulting switch statement should have. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/IfMayBeConditional.html b/plugins/InspectionGadgets/src/inspectionDescriptions/IfMayBeConditional.html index 07dbf34bee75..245111adac62 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/IfMayBeConditional.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/IfMayBeConditional.html @@ -16,6 +16,7 @@ may be expressed as:

       bar = foo == null ? null : foo.get();
     
    +

    Use the checkbox below to let this inspection report if statements containing method calls which can be replaced with a single method call with a conditional expression argument. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/IfStatementWithIdenticalBranches.html b/plugins/InspectionGadgets/src/inspectionDescriptions/IfStatementWithIdenticalBranches.html index 2a971198b3d4..e1c1ca5f40b1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/IfStatementWithIdenticalBranches.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/IfStatementWithIdenticalBranches.html @@ -3,6 +3,7 @@ This inspection reports if statements with identical "then" and else branches. Such statements are almost certainly programmer error. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/IfStatementWithTooManyBranches.html b/plugins/InspectionGadgets/src/inspectionDescriptions/IfStatementWithTooManyBranches.html index cb3ab997d606..425f18c85870 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/IfStatementWithTooManyBranches.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/IfStatementWithTooManyBranches.html @@ -3,6 +3,7 @@ This inspection reports if statements with too many branches. Such statements may be confusing, and are often the sign of inadequate levels of design abstraction. +

    Use the field provided below to specify the maximum number of branches expected.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/IgnoreResultOfCall.html b/plugins/InspectionGadgets/src/inspectionDescriptions/IgnoreResultOfCall.html index eeafa61f205e..643f05700930 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/IgnoreResultOfCall.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/IgnoreResultOfCall.html @@ -7,6 +7,7 @@ the result of a call is likely to be an error include java.io.inputStream.rea which returns the number of bytes actually read, any method on java.lang.String or java.math.BigInteger, as all of those methods are side-effect free and thus pointless if ignored. +

    Use the panel below to enter the class names and method names of the methods you wish to check for ignored returns. Class names must be specified as a simple string, while method names may be diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/IgnoredJUnitTest.html b/plugins/InspectionGadgets/src/inspectionDescriptions/IgnoredJUnitTest.html index 916df4325f86..33cc38bcb97f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/IgnoredJUnitTest.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/IgnoredJUnitTest.html @@ -1,6 +1,7 @@ -This inspection reports JUnit tests which are annotated with @Ignore. +This inspection reports JUnit tests which are annotated with @Ignore. +

    New in 11, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ImplicitArrayToString.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ImplicitArrayToString.html index 167c4c6ba2f2..7040876f85b5 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ImplicitArrayToString.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ImplicitArrayToString.html @@ -4,6 +4,7 @@ This inspection reports any arrays used in String concatenations or as parameters to java.io.PrintStream methods (such as System.out.println()). Usually in such a case, the contents of the array were meant to be used and the not array object itself. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ImplicitCallToSuper.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ImplicitCallToSuper.html index 4c4d5e466389..c0d36e2a52a2 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ImplicitCallToSuper.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ImplicitCallToSuper.html @@ -4,6 +4,7 @@ This inspection reports constructors which do not begin with calls to "super" co other constructors of the same class. Such constructors can be thought of as implicitly beginning with a call to super(). Some coding standards prefer that such calls to super() be made explicitly. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ImplicitNumericConversion.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ImplicitNumericConversion.html index b80804254658..a1f747e9800c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ImplicitNumericConversion.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ImplicitNumericConversion.html @@ -3,13 +3,14 @@ This inspection reports implicit conversion between numeric types. Implicit numeric conversion is not a problem in itself, but if unexpected may be a source of difficult to trace bugs. +

    Use the first checkbox below if you wish this inspection to ignore implicit conversions which can not result in loss of data (e.g. int->long). -
    Use the second checkbox to indicate that this inspection should ignore all conversions from +

    Use the second checkbox to indicate that this inspection should ignore all conversions from and to char. -
    Use the third checkbox to let this inspection ignore all conversions from literals and +

    Use the third checkbox to let this inspection ignore all conversions from literals and compile time constants.

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/IncompatibleMask.html b/plugins/InspectionGadgets/src/inspectionDescriptions/IncompatibleMask.html index 7e5a1e1ebe46..fc96945f2791 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/IncompatibleMask.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/IncompatibleMask.html @@ -5,6 +5,7 @@ evaluate to true or false. Expressions checked are of the form (var & constant1) == constant2 or (var | constant1) == constant2, where constant1 and constant2 are incompatible bitmask constants. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/IncrementDecrementUsedAsExpression.html b/plugins/InspectionGadgets/src/inspectionDescriptions/IncrementDecrementUsedAsExpression.html index 72c3c9e97b89..d1179ea334b5 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/IncrementDecrementUsedAsExpression.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/IncrementDecrementUsedAsExpression.html @@ -3,6 +3,7 @@ This inspection reports increment or decrement expressions nested inside other expressions. While admirably terse, such expressions may be confusing, and violate the general design principle that a given construct should do precisely one thing. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/IndexOfReplaceableByContains.html b/plugins/InspectionGadgets/src/inspectionDescriptions/IndexOfReplaceableByContains.html index 8440396e088a..4639220fe105 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/IndexOfReplaceableByContains.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/IndexOfReplaceableByContains.html @@ -6,6 +6,7 @@ expressions which can be replaced with a call to the

    This inspection only reports if the project or module is configured to use a language level of 5.0 or higher. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/InfiniteLoopStatement.html b/plugins/InspectionGadgets/src/inspectionDescriptions/InfiniteLoopStatement.html index 813e2c6dd316..fe10bc41c1d8 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/InfiniteLoopStatement.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/InfiniteLoopStatement.html @@ -4,6 +4,7 @@ This inspection reports for, while, or do statements which can only exit by throwing an exception. While such statements may be correct, they are often a symptom of coding errors. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/InfiniteRecursion.html b/plugins/InspectionGadgets/src/inspectionDescriptions/InfiniteRecursion.html index b280febe3905..064cd56f2747 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/InfiniteRecursion.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/InfiniteRecursion.html @@ -3,6 +3,7 @@ This inspection reports methods which must either recurse infinitely or throw an exception. Methods reported by this inspection can not return normally. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/InnerClassMayBeStatic.html b/plugins/InspectionGadgets/src/inspectionDescriptions/InnerClassMayBeStatic.html index 4761460a26a1..abfb36500975 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/InnerClassMayBeStatic.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/InnerClassMayBeStatic.html @@ -3,6 +3,7 @@ This inspection reports any inner classes which may safely be made static. An inner class may be static if it doesn't reference its enclosing class instance. A static inner class uses slightly less memory. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/InnerClassOnInterface.html b/plugins/InspectionGadgets/src/inspectionDescriptions/InnerClassOnInterface.html index 9f9a31233c46..95629ffc78a7 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/InnerClassOnInterface.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/InnerClassOnInterface.html @@ -4,6 +4,7 @@ This inspection reports inner classes of interface classes. Some coding standards discourage such classes. Enumeration classes and annotation classes are not reported by this inspection. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/InnerClassVariableHidesOuterClassVariable.html b/plugins/InspectionGadgets/src/inspectionDescriptions/InnerClassVariableHidesOuterClassVariable.html index a4461984d35a..d1a1911f60af 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/InnerClassVariableHidesOuterClassVariable.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/InnerClassVariableHidesOuterClassVariable.html @@ -2,6 +2,7 @@ This inspection reports inner class variables being named identically to member variables of a containing class. Such a variable name may be confusing. +

    Use the checkbox below the indicate whether this inspection should report all name clashes, or only clashes with fields which are visible from the inner class. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceMethodNamingConvention.html b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceMethodNamingConvention.html index ee238836d7e1..a933b2648864 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceMethodNamingConvention.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceMethodNamingConvention.html @@ -3,6 +3,7 @@ This inspection reports instance methods whose names are either too short, too long, or do not follow the specified regular expression pattern. Instance methods that override library methods are ignored by this inspection. +

    Use the fields provided below to specify minimum length, maximum length and regular expression expected for instance method names. (Regular expressions are in standard java.util.regex format.) diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceVariableInitialization.html b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceVariableInitialization.html index 496abb82dbe9..23ce77241843 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceVariableInitialization.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceVariableInitialization.html @@ -2,10 +2,11 @@ This inspection reports instance variables which are not guaranteed to be initialized upon object initialization.

    -Use the checkbox below to indicate whether you want uninitialized primitive fields to be reported. -

    Note: This inspection uses a very conservative dataflow algorithm, and may report instance variables as uninitialized incorrectly. Variables reported as initialized will always be initialized. + +

    +Use the checkbox below to indicate whether you want uninitialized primitive fields to be reported.

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceVariableNamingConvention.html b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceVariableNamingConvention.html index 7fdb10c53409..e5ec6483d18f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceVariableNamingConvention.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceVariableNamingConvention.html @@ -2,6 +2,7 @@ This inspection reports instance variables whose names are either too short, too long, or do not follow the specified regular expression pattern. +

    Use the fields provided below to specify minimum length, maximum length and regular expression expected for instance variable names. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceVariableOfConcreteClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceVariableOfConcreteClass.html index b0fe998da6a7..b742d317e6f5 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceVariableOfConcreteClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceVariableOfConcreteClass.html @@ -3,6 +3,7 @@ This inspection reports any instance fields whose type is declared to be a concrete class, rather than an interface. Such declarations may represent a failure of abstraction, and may make testing more difficult. Declarations whose classes come from system or third-party libraries will not be reported by this inspection. +

    Use the checkbox below to have this inspection ignore instance fields whose type is an abstract class.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofCatchParameter.html b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofCatchParameter.html index 48768ab7773c..fb2a3c180a35 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofCatchParameter.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofCatchParameter.html @@ -3,6 +3,7 @@ This inspection reports any instanceof expressions on catch block parameters. Testing the type of catch parameters is usually better done by having separate catch blocks, rather than instanceof. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofChain.html b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofChain.html index a8e1c7eaf5ce..b3f7605c5562 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofChain.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofChain.html @@ -4,6 +4,7 @@ This inspection reports any chains of if-else statements all of whose conditions (or combinations of such expressions). Such constructions usually indicate a failure of object-oriented design, which dictates that such type-based dispatch should be done via polymorphic method calls rather than explicit chains of type tests. +

    Use the checkbox below to ignore instanceof expressions on library classes.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofIncompatibleInterface.html b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofIncompatibleInterface.html index 0ffc8348e8e9..131ca3a28a43 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofIncompatibleInterface.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofIncompatibleInterface.html @@ -6,6 +6,7 @@ implements the compared interface, nor has any visible subclasses which implemen While it is possible that this was intended, such a construct is most likely an error, where the resulting instanceof expression always evaluates to false +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofInterfaces.html b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofInterfaces.html index 99db1657d152..8d523346bee6 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofInterfaces.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofInterfaces.html @@ -3,6 +3,7 @@ This inspection reports on uses of instanceof where the type checked for is a concrete class, rather than an interface. Such uses often indicate excessive coupling to concrete implementations, rather than abstractions. instanceof expressions whose classes come from system or third-party libraries will not be reported by this inspection. +

    Use the checkbox below to have this inspection ignore instanceof on abstract classes.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofThis.html b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofThis.html index 8f3ff23d49c4..0a96a2ca4df2 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofThis.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/InstanceofThis.html @@ -4,6 +4,7 @@ This inspection reports on uses of instanceof where the expression checked is this. Such expressions are indicative of a failure of object-oriented design, and should be replaced by polymorphic constructions. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/InstantiatingObjectToGetClassObject.html b/plugins/InspectionGadgets/src/inspectionDescriptions/InstantiatingObjectToGetClassObject.html index a0512fbcf5b5..e100ba383a4a 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/InstantiatingObjectToGetClassObject.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/InstantiatingObjectToGetClassObject.html @@ -3,6 +3,7 @@ This inspection reports any cases where new objects are instantiated for the purpose of accessing its class object. It is more performant to access the class object directly by name. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/InstantiationOfUtilityClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/InstantiationOfUtilityClass.html index 521e5903e793..9a21072aade7 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/InstantiationOfUtilityClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/InstantiationOfUtilityClass.html @@ -4,6 +4,7 @@ This inspection reports any new expressions which instantiate utility cla Utility classes have all fields and methods declared static, and their presence may indicate a lack of object-oriented design. Instantiation of such classes most likely indicates programmer error. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/IntLiteralMayBeLongLiteral.html b/plugins/InspectionGadgets/src/inspectionDescriptions/IntLiteralMayBeLongLiteral.html index 139171c86ce6..16c42076d529 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/IntLiteralMayBeLongLiteral.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/IntLiteralMayBeLongLiteral.html @@ -4,6 +4,7 @@ This inspection reports int literal expressions which are immediately cast to long. Such literal expressions can be replaced with the equivalent long literal. +

    New in 9, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/IntegerDivisionInFloatingPointContext.html b/plugins/InspectionGadgets/src/inspectionDescriptions/IntegerDivisionInFloatingPointContext.html index 34840b861e60..4ffbecf5cc3c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/IntegerDivisionInFloatingPointContext.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/IntegerDivisionInFloatingPointContext.html @@ -4,6 +4,7 @@ This inspection reports integer division where the result is either directly or indirectly used as a floating point number. Such division is often an error, and may result in unexpected results due to truncation in integer division. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/IntegerMultiplicationImplicitCastToLong.html b/plugins/InspectionGadgets/src/inspectionDescriptions/IntegerMultiplicationImplicitCastToLong.html index b8f997c55025..bf7e536a7b84 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/IntegerMultiplicationImplicitCastToLong.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/IntegerMultiplicationImplicitCastToLong.html @@ -3,6 +3,7 @@ This inspection reports integer multiplication or left shift which are implicitly cast to long. Such multiplication is often an error, as overflow truncation may occur unexpectedly. +

    Use the checkbox below to ignore compile time constant expressions which evaluate to a non-overflowing value. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/InterfaceNamingConvention.html b/plugins/InspectionGadgets/src/inspectionDescriptions/InterfaceNamingConvention.html index c63cac41ee48..157101edbdce 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/InterfaceNamingConvention.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/InterfaceNamingConvention.html @@ -2,6 +2,7 @@ This inspection reports interfaces whose names are either too short, too long, or do not follow the specified regular expression pattern. +

    Use the fields provided below to specify minimum length, maximum length and regular expression expected for interface names. (Regular expressions are in standard java.util.regex format.) diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/InterfaceNeverImplemented.html b/plugins/InspectionGadgets/src/inspectionDescriptions/InterfaceNeverImplemented.html index 54116406d61e..b8b0959bb579 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/InterfaceNeverImplemented.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/InterfaceNeverImplemented.html @@ -1,6 +1,7 @@ This inspection reports interfaces which have no concrete subclasses. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/InterfaceWithOnlyOneDirectInheritor.html b/plugins/InspectionGadgets/src/inspectionDescriptions/InterfaceWithOnlyOneDirectInheritor.html index 977b439b3577..fd553dda9e75 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/InterfaceWithOnlyOneDirectInheritor.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/InterfaceWithOnlyOneDirectInheritor.html @@ -8,6 +8,7 @@ direct inheritor. While such interfaces may offer admirable clarity of design, in memory-constrained or bandwidth-limited environments, they needlessly increase the total footprint of the application. Consider merging the interface with its inheritor. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/IteratorHasNextCallsIteratorNext.html b/plugins/InspectionGadgets/src/inspectionDescriptions/IteratorHasNextCallsIteratorNext.html index 11766684465e..f0110fae491b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/IteratorHasNextCallsIteratorNext.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/IteratorHasNextCallsIteratorNext.html @@ -4,6 +4,7 @@ This inspection reports any implementations of Iterator.hasNext() which call next() on themselves. While this is a common mistake, such calls are almost certainly in error, as hasNext() should not modify the iterators state, while next() should. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/IteratorNextDoesNotThrowNoSuchElementException.html b/plugins/InspectionGadgets/src/inspectionDescriptions/IteratorNextDoesNotThrowNoSuchElementException.html index f2f1e674408a..ef2d13309318 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/IteratorNextDoesNotThrowNoSuchElementException.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/IteratorNextDoesNotThrowNoSuchElementException.html @@ -4,6 +4,7 @@ This inspection reports any implementations of Iterator.next() which can not throw java.util.NoSuchElementException. Such implementations violate the contract of java.util.Iterator, and may result in subtle bugs if the iterator is ever used in a non-standard fashion. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/JDBCExecuteWithNonConstantString.html b/plugins/InspectionGadgets/src/inspectionDescriptions/JDBCExecuteWithNonConstantString.html index 4c588ec93f9d..748c205df5e3 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/JDBCExecuteWithNonConstantString.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/JDBCExecuteWithNonConstantString.html @@ -3,6 +3,7 @@ This inspection reports the calls to java.sql.Statement.execute() or any of its variants which take a dynamically-constructed string as the query to execute. Constructed SQL statements are a common source of security breaches. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/JDBCPrepareStatementWithNonConstantString.html b/plugins/InspectionGadgets/src/inspectionDescriptions/JDBCPrepareStatementWithNonConstantString.html index 4ec87b5617cb..764b67a6027c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/JDBCPrepareStatementWithNonConstantString.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/JDBCPrepareStatementWithNonConstantString.html @@ -4,6 +4,7 @@ This inspection reports the calls to java.sql.Connection.prepareStatement()java.sql.Connection.prepareCall()or any of their variants which take a dynamically-constructed string as the statement to prepare. Constructed SQL statements are a common source of security breaches. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/JDBCResource.html b/plugins/InspectionGadgets/src/inspectionDescriptions/JDBCResource.html index a20791b3adf0..2093303db7f8 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/JDBCResource.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/JDBCResource.html @@ -8,6 +8,7 @@ by this inspection include java.sql.Connection, java.sql.PreparedStatement, java.sql.CallableStatement, and java.sql.ResultSet. +

    Use the checkbox below to specify if a JDBC resource is allowed to be opened inside a try block. This style is less desirable because it is more verbose than opening a resource diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/JNDIResource.html b/plugins/InspectionGadgets/src/inspectionDescriptions/JNDIResource.html index c41d40f8d50d..ec3a3c36f6c6 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/JNDIResource.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/JNDIResource.html @@ -6,6 +6,7 @@ block and closed in the corresponding finally block. Such resources may be inadvertently leaked if an exception is thrown before the resource is closed. JNDI resources reported by this inspection include javax.naming.InitialContext, and javax.naming.NamingEnumeration. +

    Use the checkbox below to specify if a JNDI Resource is allowed to be opened inside a try block. This style is less desirable because it is more verbose than opening a resource diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/JUnit4AnnotatedMethodInJUnit3TestCase.html b/plugins/InspectionGadgets/src/inspectionDescriptions/JUnit4AnnotatedMethodInJUnit3TestCase.html index a01aa266abcb..04475ada1283 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/JUnit4AnnotatedMethodInJUnit3TestCase.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/JUnit4AnnotatedMethodInJUnit3TestCase.html @@ -3,6 +3,7 @@ This inspection reports JUnit 4 @Test annotated methods which are located inside a class extending the abstract JUnit 3 class TestCase. Mixing JUnit API's like this is confusing and can lead to problems running the tests, e.g. method annotated with @Ignore won't be actually ignored if its name starts with test +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/JUnitAbstractTestClassNamingConvention.html b/plugins/InspectionGadgets/src/inspectionDescriptions/JUnitAbstractTestClassNamingConvention.html index 26f4a636e305..7e39447d9464 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/JUnitAbstractTestClassNamingConvention.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/JUnitAbstractTestClassNamingConvention.html @@ -4,6 +4,7 @@ This inspection reports abstract JUnit test classes whose names are either too s the specified regular expression pattern. For clarity and ease of tooling, it is a common coding standard that abstract JUnit test classes follow a specific pattern, usually requiring that the class name end with "TestCase". +

    Use the fields provided below to specify minimum length, maximum length and regular expression expected for class names. (Regular expressions are in standard java.util.regex format.) diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/JUnitTestClassNamingConvention.html b/plugins/InspectionGadgets/src/inspectionDescriptions/JUnitTestClassNamingConvention.html index 58426f102e0f..ee08146fd1f9 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/JUnitTestClassNamingConvention.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/JUnitTestClassNamingConvention.html @@ -4,6 +4,7 @@ This inspection reports JUnit test classes whose names are either too short, too the specified regular expression pattern. For clarity and ease of tooling, it is a common coding standard that concrete JUnit test classes follow a specific pattern, usually requiring that the class name end with "Test". +

    Use the fields provided below to specify minimum length, maximum length and regular expression expected for class names. (Regular expressions are in standard java.util.regex format.) diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/JavaLangImport.html b/plugins/InspectionGadgets/src/inspectionDescriptions/JavaLangImport.html index 3f1232e3990e..dc513bf94872 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/JavaLangImport.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/JavaLangImport.html @@ -4,6 +4,7 @@ This inspection reports any import statements which refer to the java. Such import statements are unnecessary. Since IDEA can automatically detect and fix such statements with its "Optimize Imports" command, this inspection is mostly useful for off-line reporting on code bases that you don't intend to change. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/JavaLangReflect.html b/plugins/InspectionGadgets/src/inspectionDescriptions/JavaLangReflect.html index 6e7c8cfcff0b..924d436ed937 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/JavaLangReflect.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/JavaLangReflect.html @@ -3,6 +3,7 @@ This inspection reports any uses of classes in the java.lang.reflect package. While powerful, reflection in Java is often slow, and may possibly be unsafe is it prevents compile-time type and exception checking. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/KeySetIterationMayUseEntrySet.html b/plugins/InspectionGadgets/src/inspectionDescriptions/KeySetIterationMayUseEntrySet.html index 3fa74038d576..3bdb51c07ae8 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/KeySetIterationMayUseEntrySet.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/KeySetIterationMayUseEntrySet.html @@ -5,6 +5,7 @@ of a java.util.Map instance, where the iterated keys are used to retrieve the values from the map. Such iteration may be more efficiently replaced by iteration over the entrySet() of the map. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/LabeledStatement.html b/plugins/InspectionGadgets/src/inspectionDescriptions/LabeledStatement.html index c77620f13822..34345f1ea535 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/LabeledStatement.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/LabeledStatement.html @@ -1,6 +1,7 @@ This inspection reports labeled statements. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/LawOfDemeter.html b/plugins/InspectionGadgets/src/inspectionDescriptions/LawOfDemeter.html index 657f2f5bdb68..9c1fa11fcbd2 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/LawOfDemeter.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/LawOfDemeter.html @@ -3,6 +3,7 @@ This inspection reports any Law of Demeter violations. See here http://en.wikipedia.org/wiki/Law_of_Demeter for an explanation what the Law of Demeter is. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/LengthOneStringInIndexOf.html b/plugins/InspectionGadgets/src/inspectionDescriptions/LengthOneStringInIndexOf.html index ddb29afe39cf..18d3db1d9cb3 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/LengthOneStringInIndexOf.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/LengthOneStringInIndexOf.html @@ -4,6 +4,7 @@ This inspection reports String literals of length one being used as a parameter in String.indexOf() or String.lastIndexOf() calls. These String literals may be replaced by equivalent character literals, gaining some performance enhancement. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/LengthOneStringsInConcatenation.html b/plugins/InspectionGadgets/src/inspectionDescriptions/LengthOneStringsInConcatenation.html index b477dce7f5dd..fdc1362ee289 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/LengthOneStringsInConcatenation.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/LengthOneStringsInConcatenation.html @@ -2,6 +2,7 @@ This inspection reports String literals of length one being used in concatenation. These literals may be replaced by equivalent character literals, gaining some performance enhancement. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/LimitedScopeInnerClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/LimitedScopeInnerClass.html index b5c802d3d4eb..8fbd9b3fcd47 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/LimitedScopeInnerClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/LimitedScopeInnerClass.html @@ -3,6 +3,7 @@ This inspection reports any limited-scope inner classes. Some code standards discourage the use of limited-scope inner classes, and they are unusual enough as to possibly be confusing. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ListIndexOfReplaceableByContains.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ListIndexOfReplaceableByContains.html index bdc1e2bcdb2e..bd0bcac85d82 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ListIndexOfReplaceableByContains.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ListIndexOfReplaceableByContains.html @@ -3,6 +3,7 @@ This inspection reports any List.indexOf() expressions which can be replaced with the method List.contains(). +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ListenerMayUseAdapter.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ListenerMayUseAdapter.html index b5904f14e9da..b5aeff8ce4cc 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ListenerMayUseAdapter.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ListenerMayUseAdapter.html @@ -4,6 +4,7 @@ This inspection reports any classes which implement a listener, but may extend the corresponding adapter instead. The quickfix for this inspection will also remove any redundant empty methods left over after replacing the implementation of the listener with an extension of the corresponding adapter. +

    Use the checkbox below to indicate if the inspection should warn even if no empty implementing methods are found. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/LiteralAsArgToStringEquals.html b/plugins/InspectionGadgets/src/inspectionDescriptions/LiteralAsArgToStringEquals.html index ba18541d1000..2463fe79eb27 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/LiteralAsArgToStringEquals.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/LiteralAsArgToStringEquals.html @@ -3,6 +3,7 @@ This inspection reports calls to .equals() whose arguments are String literals. Some coding standards specify that String literals should be the target of .equals(), rather than argument, thus minimizing NullPointerExceptions. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/LoadLibraryWithNonConstantString.html b/plugins/InspectionGadgets/src/inspectionDescriptions/LoadLibraryWithNonConstantString.html index a65b6ebbef12..f8c925626d8f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/LoadLibraryWithNonConstantString.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/LoadLibraryWithNonConstantString.html @@ -3,6 +3,7 @@ This inspection reports the calls to java.lang.System.loadLibrary() which take a dynamically-constructed string as the execution strings. Constructed library location strings are a common source of security breaches. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/LocalVariableHidingMemberVariable.html b/plugins/InspectionGadgets/src/inspectionDescriptions/LocalVariableHidingMemberVariable.html index 5a295a61f6f0..d224afc21cd5 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/LocalVariableHidingMemberVariable.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/LocalVariableHidingMemberVariable.html @@ -2,6 +2,7 @@ This inspection reports local variables being named identically to visible member variables of their class. Such a variable name may be confusing. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/LocalVariableNamingConvention.html b/plugins/InspectionGadgets/src/inspectionDescriptions/LocalVariableNamingConvention.html index 40c1843bf2d3..89fe04822395 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/LocalVariableNamingConvention.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/LocalVariableNamingConvention.html @@ -2,6 +2,7 @@ This inspection reports local variables whose names are either too short, too long, or do not follow the specified regular expression pattern. +

    Use the fields provided below to specify minimum length, maximum length and regular expression expected for local variables names. (Regular expressions are in standard java.util.regex format.) diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/LocalVariableOfConcreteClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/LocalVariableOfConcreteClass.html index 047feb34d3dc..2cf8f686d2b2 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/LocalVariableOfConcreteClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/LocalVariableOfConcreteClass.html @@ -4,6 +4,7 @@ This inspection reports any local variables whose type is declared to be a concr Such declarations may represent a failure of abstraction, and may make testing more difficult. Declarations whose classes come from system or third-party libraries will not be reported by this inspection. catch block parameters of concrete exception type will also not be reported by this inspection. +

    Use the checkbox below to have this inspection ignore local variables whose type is an abstract class.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/LogStatementGuardedByLogCondition.html b/plugins/InspectionGadgets/src/inspectionDescriptions/LogStatementGuardedByLogCondition.html index f9abf835687b..b84fa12c884e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/LogStatementGuardedByLogCondition.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/LogStatementGuardedByLogCondition.html @@ -7,6 +7,7 @@ Surrounding a log statement with a guard clause prevents that cost when the logg is disabled for the level used by the logging statement. This is especially for the least serious level (trace, debug, finest) of logging statements, because those are most often disabled in a production environment. +

    Use the text field below to specify the logger class name used. Use the table to specify the log methods this inspection should warn on, with the corresponding diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/LoggingConditionDisagreesWithLogStatement.html b/plugins/InspectionGadgets/src/inspectionDescriptions/LoggingConditionDisagreesWithLogStatement.html index 18e04f146d4c..fe999cc586ff 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/LoggingConditionDisagreesWithLogStatement.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/LoggingConditionDisagreesWithLogStatement.html @@ -9,6 +9,7 @@ For example: logger.debug("some log message"); }

    +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/LongLiteralsEndingWithLowercaseL.html b/plugins/InspectionGadgets/src/inspectionDescriptions/LongLiteralsEndingWithLowercaseL.html index 5a183269f98c..03f5a50b36da 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/LongLiteralsEndingWithLowercaseL.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/LongLiteralsEndingWithLowercaseL.html @@ -2,6 +2,7 @@ This inspection reports long literals ending with lowercase 'l'. These literals may be confusing, as lowercase 'l' looks very similar to '1'. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/LoopConditionNotUpdatedInsideLoop.html b/plugins/InspectionGadgets/src/inspectionDescriptions/LoopConditionNotUpdatedInsideLoop.html index 6a74555be54c..d248b6442e6e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/LoopConditionNotUpdatedInsideLoop.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/LoopConditionNotUpdatedInsideLoop.html @@ -3,6 +3,7 @@ This inspection reports any variables and parameters which are used in a loop condition and are not updated inside the loop. These may cause an infinite loop if executed and are probably not what was intended. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/LoopStatementsThatDontLoop.html b/plugins/InspectionGadgets/src/inspectionDescriptions/LoopStatementsThatDontLoop.html index b27b1f5527dc..9178d380a4f4 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/LoopStatementsThatDontLoop.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/LoopStatementsThatDontLoop.html @@ -3,6 +3,7 @@ This inspection reports any instance of for, while and do statements whose bodies are guaranteed to execute at most once. Normally, this is an indication of a bug. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/LoopWithImplicitTerminationCondition.html b/plugins/InspectionGadgets/src/inspectionDescriptions/LoopWithImplicitTerminationCondition.html index 16a63d94b4b0..bb44c4041fa5 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/LoopWithImplicitTerminationCondition.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/LoopWithImplicitTerminationCondition.html @@ -10,6 +10,7 @@ in a while or for loops and the last or only statement in a do-while loop. Such a loop would be clearer if the if statement was removed and its condition was made an explicit loop condition. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MagicCharacter.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MagicCharacter.html index e837d725f844..11efc4a39ebb 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MagicCharacter.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MagicCharacter.html @@ -4,6 +4,7 @@ This inspection reports "magic characters", character constants used without dec "Magic character" can result in code whose intention is extremely unclear, and may result in errors if a "magic character" is changed in one code location but not another. Such use can complicate internationalization efforts. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MagicNumber.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MagicNumber.html index 38e1d5b28aff..e34b4d709f5a 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MagicNumber.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MagicNumber.html @@ -4,6 +4,7 @@ This inspection reports "magic numbers", literal numeric constants used without "Magic numbers" can result in code whose intention is extremely unclear, and may result in errors if a "magic number" is changed in one code location but not another. The numbers 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100, 1000, 0L, 1L, 2L, 0.0, 1.0, 0.0F and 1.0F are not reported by this inspection. +

    Use the first checkbox below to disable this inspection within hashCode() methods.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MalformedFormatString.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MalformedFormatString.html index 76438f737a41..7e405dd4b0b8 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MalformedFormatString.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MalformedFormatString.html @@ -7,6 +7,7 @@ are reported if they are compile-time constants used as arguments to appropriate java.io.PrintWriter, or java.io.PrintStream and do not fit the standard Java format string syntax. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MalformedRegex.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MalformedRegex.html index 575c040362ce..53d749afbd1b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MalformedRegex.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MalformedRegex.html @@ -4,6 +4,7 @@ This inspection reports malformed regular expressions. Regular expressions are reported if they are compile-time constants used as arguments to appropriate methods on java.util.regex.Pattern or java.lang.String and do not fit the standard Java regular expression syntax. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MalformedXPath.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MalformedXPath.html index 0d8ce5e49fbe..90679a411456 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MalformedXPath.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MalformedXPath.html @@ -3,6 +3,7 @@ This inspection reports malformed XPath expressions. XPath expressions are reported if they are compile-time constants used as arguments to appropriate methods on javax.xml.xpath.XPath and do not fit the standard XPath syntax. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ManualArrayCopy.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ManualArrayCopy.html index 59c83e039248..bf5f36766d59 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ManualArrayCopy.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ManualArrayCopy.html @@ -2,6 +2,7 @@ This inspection reports the manual copying of array contents which may be replaced by calls to System.arraycopy(). +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ManualArrayToCollectionCopy.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ManualArrayToCollectionCopy.html index 3b80053388ba..a50cf510befe 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ManualArrayToCollectionCopy.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ManualArrayToCollectionCopy.html @@ -2,8 +2,7 @@ This inspection reports the copying of array contents to a collection where each element is added individually using a for loop. Such constructs may be replaced by a call to Collection.addAll(Arrays.asList()) or Collections.addAll(). -
    -This inspection provides a quick fix. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MapReplaceableByEnumMap.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MapReplaceableByEnumMap.html index 4d775152e101..fa1bf7feb649 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MapReplaceableByEnumMap.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MapReplaceableByEnumMap.html @@ -5,6 +5,7 @@ whose key types are enumerated classes. Such java.util.Map objects can be replaced by java.util.EnumMap objects. java.util.EnumMap implementations can be much more efficient that those of other sets, as the underlying data structure is a simple array. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MarkerInterface.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MarkerInterface.html index 2f2c1cb33071..502650107988 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MarkerInterface.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MarkerInterface.html @@ -4,6 +4,7 @@ This inspection reports "marker" interfaces which have no methods or fields. Such interfaces may be confusing, and normally indicate a design failure. Interfaces which extend two or more other interfaces will not be reported by this inspection. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MathRandomCastToInt.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MathRandomCastToInt.html index 5b4fb172da90..8bbde8ebf4d0 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MathRandomCastToInt.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MathRandomCastToInt.html @@ -7,6 +7,7 @@ should first be multiplied with some factor before casting it to an int t get a value between zero (inclusive) and the multiplication factor (exclusive). Another possible solution would be to use the nextInt() method of java.util.Random. +

    New in 10.5, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCallInLoopCondition.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCallInLoopCondition.html index 25f9de0c6c45..507ee816f773 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCallInLoopCondition.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCallInLoopCondition.html @@ -6,6 +6,7 @@ Applying the results of this inspection without consideration might have negativ This inspection reports method calls in the condition part of a loop statement. In highly resource constrained environments, such calls may have adverse performance implications +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCanBeVariableArityMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCanBeVariableArityMethod.html index ac5e248ddcc6..7d5121276359 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCanBeVariableArityMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCanBeVariableArityMethod.html @@ -5,6 +5,7 @@ arity/varargs method, available in Java 5 and newer.

    This inspection only reports if the project or module is configured to use a language level of 5.0 or higher. +

    New in 10.5, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCount.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCount.html index 568d6cd5eda0..c52881208c79 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCount.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCount.html @@ -3,6 +3,7 @@ This inspection reports any classes with too many methods. Classes with a large number of methods are often trying to 'do too much', and may need to be refactored into multiple smaller classes. +

    Use the field provided below to specify the maximum acceptable number of methods a class might have. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCoupling.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCoupling.html index 16ac3d180f33..9439750e7e23 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCoupling.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCoupling.html @@ -4,6 +4,7 @@ This inspection reports methods which are highly coupled, i.e. that reference to Methods with too high a coupling can be very fragile, and should probably be broken up. References to system classes (those in the java.or javax. packages), are not counted for purposes of this inspection. +

    Use the field provided below to specify the maximum acceptable coupling a method might have.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodMayBeStatic.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodMayBeStatic.html index 8d7cb26cf370..4b3a229ce8f6 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodMayBeStatic.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodMayBeStatic.html @@ -3,6 +3,7 @@ This inspection reports any methods which may safely be made static. A method may be static if it is not synchronized, it does not reference any of its class' non static methods and non static fields and is not overridden in a sub class. +

    Use the checkboxes below to inspect only private or final methods, which increases the diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodMayBeSynchronized.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodMayBeSynchronized.html index 64a8d1a820d1..2f3f55619508 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodMayBeSynchronized.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodMayBeSynchronized.html @@ -7,6 +7,7 @@ equal to this for instance methods or ClassName.class for static methods. In such cases the synchronized statements may be replaced by their contents and the containing method marked synchronized. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodNameSameAsClassName.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodNameSameAsClassName.html index 6605a791566b..8119a68fb912 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodNameSameAsClassName.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodNameSameAsClassName.html @@ -2,6 +2,7 @@ This inspection reports methods being named identically to their class. A method with such a name may be easily mistaken for a constructor. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodNameSameAsParentName.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodNameSameAsParentName.html index 075633dc67ea..144dd6cf6d17 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodNameSameAsParentName.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodNameSameAsParentName.html @@ -2,6 +2,7 @@ This inspection reports methods being named identically to the superclass of the method's class. Such a method name may be confusing. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodNamesDifferOnlyByCase.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodNamesDifferOnlyByCase.html index 95e051ac217e..11f96f81881d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodNamesDifferOnlyByCase.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodNamesDifferOnlyByCase.html @@ -2,6 +2,7 @@ This inspection reports on cases where multiple methods of a class have names which differ only by case. Such method names may be very confusing. +

    Use the checkbox below to have this inspection ignore methods which are overrides or implementations of super methods.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodOnlyUsedFromInnerClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodOnlyUsedFromInnerClass.html index dc2b788d47cc..822b4df2a0ca 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodOnlyUsedFromInnerClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodOnlyUsedFromInnerClass.html @@ -3,6 +3,7 @@ This inspection reports private methods, which are only called from an inner class of the class containing the method. Such methods could be safely moved into that inner class. +

    Use the first checkbox below to ignore private methods which are called from an anonymous class. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodOverloadsParentMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodOverloadsParentMethod.html index 93f41f5de9bd..1255e5350a76 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodOverloadsParentMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodOverloadsParentMethod.html @@ -3,6 +3,7 @@ This inspection reports instance methods having the same name and different but compatible arguments as a method in a superclass. In this case, the child method overloads the parent method, instead of overriding it. While that may be intended, if unintended it may result in latent bugs. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodOverridesPackageLocalMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodOverridesPackageLocalMethod.html index 3ef86e4d2b8c..edbbac90129b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodOverridesPackageLocalMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodOverridesPackageLocalMethod.html @@ -5,6 +5,7 @@ local method of a superclass in other package. Such methods may result in confusing semantics, particularly if the package local method is ever made publicly visible. A package local method can only properly be overridden if the subclass resides in the same package. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodOverridesPrivateMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodOverridesPrivateMethod.html index 74a2b30015c9..02662dd63573 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodOverridesPrivateMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodOverridesPrivateMethod.html @@ -4,6 +4,7 @@ This inspection reports instance methods having the same name as a private method of a superclass. Such methods may result in confusing semantics, particularly if the private method is ever made publicly visible. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodOverridesStaticMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodOverridesStaticMethod.html index cf26b0b3909f..0472bd14c108 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodOverridesStaticMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodOverridesStaticMethod.html @@ -2,6 +2,7 @@ This inspection reports methods having the same name as a static method of a superclass. Such methods may result in confusing semantics. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodReturnAlwaysConstant.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodReturnAlwaysConstant.html index 9b48555a344d..f6898339fa6c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodReturnAlwaysConstant.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodReturnAlwaysConstant.html @@ -2,6 +2,7 @@ This global inspection reports methods which only ever return a constant. Since this inspection requires global code analysis, it is only available in batch inspection mode. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodReturnOfConcreteClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodReturnOfConcreteClass.html index b3d7b389cc11..000b6713b12d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodReturnOfConcreteClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodReturnOfConcreteClass.html @@ -3,6 +3,7 @@ This inspection reports any methods whose return type is declared to be a concrete class, rather than an interface. Such declarations may represent a failure of abstraction, and may make testing more difficult. Declarations whose classes come from system or third-party libraries will not be reported by this inspection. +

    Use the checkbox below to have this inspection ignore methods whose return type is an abstract class.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodWithMultipleLoops.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodWithMultipleLoops.html index 2a9aebf3aef0..c1430cc2ba00 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodWithMultipleLoops.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodWithMultipleLoops.html @@ -1,6 +1,7 @@ This inspection reports methods containing multiple loop statements. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MismatchedArrayReadWrite.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MismatchedArrayReadWrite.html index f2f680dbae26..0ef4e1afd447 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MismatchedArrayReadWrite.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MismatchedArrayReadWrite.html @@ -3,6 +3,7 @@ This inspection reports any array fields or variables whose contents are read but not written, or written but not read. Such mismatched reads and writes are pointless, and probably indicate dead, incomplete or erroneous code. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MismatchedCollectionQueryUpdate.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MismatchedCollectionQueryUpdate.html index 8daa1ad563a4..67e050c1633f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MismatchedCollectionQueryUpdate.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MismatchedCollectionQueryUpdate.html @@ -3,6 +3,7 @@ This inspection reports collection fields or variables whose contents are either queried and not updated, or updated and not queried. Such mismatched queries and updates are pointless, and may indicate either dead code or a typographical error. +

    Use the tables below to specify which methods are update and/or query methods. The names are matched with the beginning of the method name. Query methods which return their result are automatically detected, only diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MismatchedStringBuilderQueryUpdate.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MismatchedStringBuilderQueryUpdate.html index e90bc982f551..c98107de05a4 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MismatchedStringBuilderQueryUpdate.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MismatchedStringBuilderQueryUpdate.html @@ -3,6 +3,7 @@ This inspection reports any StringBuilder or StringBuffer fields or variables whose contents are read but not written, or written but not read. Such mismatched reads and writes are pointless, and probably indicate dead, incomplete or erroneous code. +

    New in 10.5, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MisorderedAssertEqualsParameters.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MisorderedAssertEqualsParameters.html index c1acdf73f5cf..f4bd985ff056 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MisorderedAssertEqualsParameters.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MisorderedAssertEqualsParameters.html @@ -4,6 +4,7 @@ This inspection reports any calls to JUnit assertEquals() which have a non-literal as the expected result argument and a literal as the actual result argument. Such calls will behave fine for assertions which pass, but may give confusing error reports if their expected and actual arguments differ. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MissingDeprecatedAnnotation.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MissingDeprecatedAnnotation.html index 9e0b583cb87b..5730c13fb0ce 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MissingDeprecatedAnnotation.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MissingDeprecatedAnnotation.html @@ -5,6 +5,7 @@ javadoc tag but do not have the @java.lang.Deprecated annotation.

    This inspection only reports if the project or module is configured to use a language level of 5.0 or higher. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MissingOverrideAnnotation.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MissingOverrideAnnotation.html index a534a8f62577..1891aa2645e2 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MissingOverrideAnnotation.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MissingOverrideAnnotation.html @@ -5,6 +5,7 @@ do not have the @java.lang.Override annotation.

    This inspection only reports if the project or module is configured to use a language level of 5.0 or higher. +

    Use the first checkbox below to have this inspection ignore the java.lang.Object methods diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MissortedModifiers.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MissortedModifiers.html index 13bd7e59978b..0ea060905fea 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MissortedModifiers.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MissortedModifiers.html @@ -1,7 +1,8 @@ This inspection reports on declarations whose modifiers are not in the canonical -preferred order (as stated in the Java Language Specification). +preferred order (as stated in the Java Language Specification). +

    Use the checkbox below to specify that annotations should always be sorted before keyword modifiers.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledCompareTo.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledCompareTo.html index d88cc3224c5b..c5a235792dc1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledCompareTo.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledCompareTo.html @@ -2,6 +2,7 @@ This inspection reports any declaration of a compareto() method, taking one argument. Normally, this is a typo of compareTo(). +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledEquals.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledEquals.html index cf230d8d11e7..bbaa9160615f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledEquals.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledEquals.html @@ -2,6 +2,7 @@ This inspection reports any declaration of a equal() method, taking one argument. Normally, this is a typo of equals(). +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledHashcode.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledHashcode.html index b719ca857d86..4bdcbd1f7ea1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledHashcode.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledHashcode.html @@ -2,6 +2,7 @@ This inspection reports any declaration of a hashcode() method, taking no arguments. Normally, this is a typo of hashCode(). +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledSetUp.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledSetUp.html index eec4450cca33..37c416323fdb 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledSetUp.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledSetUp.html @@ -2,6 +2,7 @@ This inspection reports a setup() method on a JUnit test case. This is normally a misspelling of setUp(), and is entirely too easy to make. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledTearDown.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledTearDown.html index 637e470879ed..161722056d7f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledTearDown.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledTearDown.html @@ -2,6 +2,7 @@ This inspection reports a teardown() method on a JUnit test case. This is normally a misspelling of tearDown(), and is entirely too easy to make. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledToString.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledToString.html index 8f61a93ab119..2c46b7f7b895 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledToString.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MisspelledToString.html @@ -2,6 +2,7 @@ This inspection reports any declaration of a tostring() method, taking one argument. Normally, this is a typo of toString(). +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ModuleWithTooFewClasses.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ModuleWithTooFewClasses.html index 7c2cbf2b0270..38dbc50a9962 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ModuleWithTooFewClasses.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ModuleWithTooFewClasses.html @@ -3,6 +3,7 @@ This global inspection reports any modules which contain too few classes. Overly small modules may indicate an overly fragmented design. Since this inspection requires global code analysis, it is only available in batch inspection mode. +

    Use the field below to specify the minimum number of classes a module may have before triggering this inspection.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ModuleWithTooManyClasses.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ModuleWithTooManyClasses.html index e68789183866..d167a24a4af2 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ModuleWithTooManyClasses.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ModuleWithTooManyClasses.html @@ -3,6 +3,7 @@ This global inspection reports any modules which contain too many classes. Overly large modules may indicate a lack of design clarity. Since this inspection requires global code analysis, it is only available in batch inspection mode. +

    Use the field below to specify the maximum number of classes a module may have before triggering this inspection.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MultipleDeclaration.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MultipleDeclaration.html index 87b0025e061f..cc22f75aab14 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MultipleDeclaration.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MultipleDeclaration.html @@ -2,6 +2,7 @@ This inspection reports multiple variables being declared in a single declaration. Some coding standards prohibit such declarations. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MultipleExceptionsDeclaredOnTestMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MultipleExceptionsDeclaredOnTestMethod.html index e324836abad2..29ca3c323c40 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MultipleExceptionsDeclaredOnTestMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MultipleExceptionsDeclaredOnTestMethod.html @@ -4,6 +4,7 @@ This inspection reports JUnit test methods with more than one exception declared throws clause. Such a throws clause can be more concisely declared as:

    throws Exception
    +

    New in 9, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MultipleReturnPointsPerMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MultipleReturnPointsPerMethod.html index fefef7e24a1d..e5d737a8cfc3 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MultipleReturnPointsPerMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MultipleReturnPointsPerMethod.html @@ -2,6 +2,7 @@ This inspection reports methods with too many return points. Methods with too many return points may be confusing, and hard to refactor. +

    Use the field provided below to specify the maximum acceptable number of return points a method might have. Use the check boxes below to specify if guard clause and/or return points inside diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MultipleTopLevelClassesInFile.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MultipleTopLevelClassesInFile.html index 24bd9dd39b3a..880679780650 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MultipleTopLevelClassesInFile.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MultipleTopLevelClassesInFile.html @@ -3,6 +3,7 @@ This inspection reports multiple top-level classes in a single java file. Putting multiple top-level classes in a file can be confusing, and may degrade the usefulness of various software tools. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MultipleTypedDeclaration.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MultipleTypedDeclaration.html index 935eea775c81..3355b41b9ca5 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MultipleTypedDeclaration.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MultipleTypedDeclaration.html @@ -4,6 +4,7 @@ This inspection reports multiple different types of variables being declared in used can only differ in array dimension. Such declarations may be confusing.

    For example the following will be reported by this inspection:

    String s = "", array[];
    +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MultiplyOrDivideByPowerOfTwo.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MultiplyOrDivideByPowerOfTwo.html index 3ccd8542d682..42309d6ca58e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MultiplyOrDivideByPowerOfTwo.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MultiplyOrDivideByPowerOfTwo.html @@ -2,6 +2,7 @@ This inspection reports multiplication of an integer value by a constant power of 2. These expressions may be replaced by right or left shift operations, to some possible performance improvement. +

    Use the check box below to enable the inspection for divisions by a power of two also. Note that replacing a power of two division by a shift does not work for negative numbers. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NakedNotify.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NakedNotify.html index d32e38623b86..6412ddbcaa62 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NakedNotify.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NakedNotify.html @@ -7,6 +7,7 @@ used to inform other threads that a state change has occurred. That state change context that contains the .notify() or .notifyAll() call, and prior to the call. While not having such a state change isn't necessarily incorrect, it is certainly worth examining. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NativeMethods.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NativeMethods.html index 67ac495b9525..7d173f513c28 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NativeMethods.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NativeMethods.html @@ -1,6 +1,7 @@ This inspection reports the methods declared native. Native methods are inherently unportable. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NegatedConditional.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NegatedConditional.html index b8d4f9cb6fd7..c00a47126c92 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NegatedConditional.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NegatedConditional.html @@ -2,6 +2,7 @@ This inspection reports conditional expressions whose conditions are negated. Flipping the order of the conditional expression branches will usually increase the clarity of such statements. +

    Use the check box below to have comparisons of the form != null ignored by this inspection diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NegatedIfElse.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NegatedIfElse.html index 764f36aa00fa..8364eb9bda57 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NegatedIfElse.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NegatedIfElse.html @@ -4,6 +4,7 @@ This inspection reports if statements which contain else branches and whose conditions are negated. Flipping the order of the if and else branches will usually increase the clarity of such statements. +

    Use the check box below to have comparisons of the form != null ignored by this inspection diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NestedAssignment.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NestedAssignment.html index dcae2c2bf2a8..6ff8df95f60d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NestedAssignment.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NestedAssignment.html @@ -2,6 +2,7 @@ This inspection reports assignment expressions nested inside other expressions. While admirably terse, such expressions may be confusing, and violate the general design principle that a given construct should do precisely one thing. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NestedConditionalExpression.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NestedConditionalExpression.html index 804dad80192c..49dbe6aa0799 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NestedConditionalExpression.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NestedConditionalExpression.html @@ -2,6 +2,7 @@ This inspection reports nested conditional expressions. Nested conditional expressions may result in extremely confusing code. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NestedMethodCall.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NestedMethodCall.html index d54b7623240b..81842f0dbb26 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NestedMethodCall.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NestedMethodCall.html @@ -2,6 +2,7 @@ This inspection reports method calls used as parameters of another method call. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NestedSwitchStatement.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NestedSwitchStatement.html index fc2388854aed..e7583b097a5a 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NestedSwitchStatement.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NestedSwitchStatement.html @@ -2,6 +2,7 @@ This inspection reports nested switch statements. Nested switch statements may result in extremely confusing code. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NestedSynchronizedStatement.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NestedSynchronizedStatement.html index 0df4a37f7bea..0955cf8f1508 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NestedSynchronizedStatement.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NestedSynchronizedStatement.html @@ -2,6 +2,7 @@ This inspection reports nested synchronized statements. Nested synchronized statements are either useless (if the lock objects are identical) or prone to deadlock. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NestedTryStatement.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NestedTryStatement.html index 47c2e738b19d..b204916f4ae6 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NestedTryStatement.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NestedTryStatement.html @@ -3,6 +3,7 @@ This inspection reports nested try statements. Nested try statements may result in confusing code, and should probably have their catch and finally sections merged. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NestingDepth.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NestingDepth.html index 82d3559a38a6..46d649dd82e2 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NestingDepth.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NestingDepth.html @@ -2,6 +2,7 @@ This inspection reports methods whose bodies are too deeply nested. Methods with too much statement nesting may be confusing, and are a good sign that refactoring may be necessary. +

    Use the field provided below to specify the maximum acceptable nesting depth a method might have.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NewExceptionWithoutArguments.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NewExceptionWithoutArguments.html index 5ce387634751..6f6c9063aeb6 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NewExceptionWithoutArguments.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NewExceptionWithoutArguments.html @@ -2,6 +2,7 @@ This inspection reports exception instance creation without any arguments specified. When an exception is constructed without arguments it contains no information about the fault that happened, which makes debugging needlessly hard. +

    Use the checkbox below to ignore instance creation of exception classes which have no constructors that take arguments.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NewStringBufferWithCharArgument.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NewStringBufferWithCharArgument.html index 53c4a88457a0..e364986736f5 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NewStringBufferWithCharArgument.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NewStringBufferWithCharArgument.html @@ -5,6 +5,7 @@ and new StringBuilder() calls with an argument with type char. Such an argument is silently casted to an integer used to specify the length of the buffer. Usually this is not what was intended. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NoExplicitFinalizeCalls.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NoExplicitFinalizeCalls.html index 59be7f77d79e..18b2fa748ec1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NoExplicitFinalizeCalls.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NoExplicitFinalizeCalls.html @@ -4,6 +4,7 @@ This inspection reports any call of Object.finalize(). Calling Object.finalize() explicitly is a very bad idea, as it can result in objects being placed in an inconsistent state. Calls to super.finalize() from within implementations of finalize() are benign, and are not reported by this inspection. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NonAtomicOperationOnVolatileField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NonAtomicOperationOnVolatileField.html index cd68d3a09f3d..198a2d974e7b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NonAtomicOperationOnVolatileField.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NonAtomicOperationOnVolatileField.html @@ -8,6 +8,7 @@ In such cases it is better to surround the operation with a synchronized block o make use of one of the Atomic* or Atomic*FieldUpdater classes from the java.util.concurrent.atomic package. +

    New in 10, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NonBooleanMethodNameMayNotStartWithQuestion.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NonBooleanMethodNameMayNotStartWithQuestion.html index 55cb3aa12a09..42712d025d64 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NonBooleanMethodNameMayNotStartWithQuestion.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NonBooleanMethodNameMayNotStartWithQuestion.html @@ -2,6 +2,7 @@ This inspection reports non-boolean methods whose names start with a question word. Non-boolean methods that override library methods are ignored by this inspection. +

    Use the list below to specify question words which should only be used for boolean methods.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NonCommentSourceStatements.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NonCommentSourceStatements.html index d4241607b231..47ed454dddfd 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NonCommentSourceStatements.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NonCommentSourceStatements.html @@ -2,6 +2,7 @@ This inspection reports methods that are too long. Methods that are too long may be confusing, and are a good sign that refactoring is necessary. +

    Use the field provided below to specify the maximum acceptable number of non-comment source statements a method might have.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NonExceptionNameEndsWithException.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NonExceptionNameEndsWithException.html index 013adfa8ed6c..794818f9048b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NonExceptionNameEndsWithException.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NonExceptionNameEndsWithException.html @@ -1,6 +1,7 @@ This inspection reports non-exception classes whose names end with 'Exception'. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NonFinalClone.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NonFinalClone.html index 4fde46f67bd6..d13200d274a3 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NonFinalClone.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NonFinalClone.html @@ -6,6 +6,7 @@ be used to instantiate objects without using a constructor, allowing the clon method to be overridden may result in corrupted objects, and possible security exploits. This may be prevented by making the clone() method final. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NonFinalFieldInEnum.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NonFinalFieldInEnum.html index b8d4d271100f..2109963341b4 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NonFinalFieldInEnum.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NonFinalFieldInEnum.html @@ -1,6 +1,7 @@ This inspection reports non-final fields in enumeration types. A non-final field in an enum is rarely needed. +

    New in 12, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NonFinalFieldOfException.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NonFinalFieldOfException.html index 86ab9084fc35..e630033ad2d6 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NonFinalFieldOfException.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NonFinalFieldOfException.html @@ -5,6 +5,7 @@ This inspection reports any fields on subclasses of final. Data on exception objects should not be modified, as it may result in loss of error context for later debugging and logging. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NonFinalStaticVariableUsedInClassInitialization.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NonFinalStaticVariableUsedInClassInitialization.html index 75b2fc541781..1b2ea0295c27 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NonFinalStaticVariableUsedInClassInitialization.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NonFinalStaticVariableUsedInClassInitialization.html @@ -4,6 +4,7 @@ This inspection reports any uses of non-final static variables dur of a class. Such uses may make the semantics of the code dependent on order of class creation, may cause variables to be used before initialized, and generally cause extremely difficult and confusing bugs. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NonProtectedConstructorInAbstractClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NonProtectedConstructorInAbstractClass.html index df500267c288..e501499d1be0 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NonProtectedConstructorInAbstractClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NonProtectedConstructorInAbstractClass.html @@ -3,6 +3,7 @@ This inspection reports constructors in abstract classes that are not declared protected, package-protected or private. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NonReproducibleMathCall.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NonReproducibleMathCall.html index 67636f8870cb..7ee60dbd844e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NonReproducibleMathCall.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NonReproducibleMathCall.html @@ -4,6 +4,7 @@ This inspection reports any calls to java.lang.Math methods whose results are not guaranteed to be precisely reproducible. In environments where reproducibility of results are needed, java.lang.StrictMath should be used instead. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NonSerializableObjectBoundToHttpSession.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NonSerializableObjectBoundToHttpSession.html index a902a6d9c501..34e5cbfa2d8c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NonSerializableObjectBoundToHttpSession.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NonSerializableObjectBoundToHttpSession.html @@ -7,6 +7,7 @@ Such objects will not be serialized if the HttpSession is passivated or migrated bugs. For purposes of this inspection, objects with java.util.Collection or java.util.Map types are assumed to be Serializable, unless the types they are declared to contain are non-Serializable. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NonSerializableObjectPassedToObjectStream.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NonSerializableObjectPassedToObjectStream.html index 7e59c1419507..e95295bdb446 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NonSerializableObjectPassedToObjectStream.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NonSerializableObjectPassedToObjectStream.html @@ -5,6 +5,7 @@ This inspection reports non-Serializable objects used as arguments to For purposes of this inspection, objects with java.util.Collection or java.util.Map types are assumed to be Serializable, unless the types they are declared to contain are non-Serializable. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NonSerializableWithSerialVersionUIDField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NonSerializableWithSerialVersionUIDField.html index b34663e94e47..91a7b98befab 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NonSerializableWithSerialVersionUIDField.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NonSerializableWithSerialVersionUIDField.html @@ -2,6 +2,7 @@ This inspection reports non-Serializable classes which define a serialVersionUID field. This is usually an indication of a programmer error. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NonSerializableWithSerializationMethods.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NonSerializableWithSerializationMethods.html index e0f0f0e94618..169e52e90e02 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NonSerializableWithSerializationMethods.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NonSerializableWithSerializationMethods.html @@ -2,6 +2,7 @@ This inspection reports non-Serializable classes which define readObject() or writeObject() methods. Such methods normally indicate programmer error. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NonShortCircuitBoolean.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NonShortCircuitBoolean.html index dc848e5181b3..f1ef6ab78679 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NonShortCircuitBoolean.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NonShortCircuitBoolean.html @@ -4,6 +4,7 @@ This inspection reports on any uses of the non-short-circuit forms of boolean 'a and | ). The non-short-circuit versions are occasionally useful, but their presence is often due to typos of the short-circuit forms ( && and || ), and may lead to subtle bugs. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NonStaticInnerClassInSecureContext.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NonStaticInnerClassInSecureContext.html index 7f8896e69f2a..1c202078343c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NonStaticInnerClassInSecureContext.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NonStaticInnerClassInSecureContext.html @@ -3,6 +3,7 @@ This inspection reports non-static inner classes. Compilation of such classes causes the creation of hidden, package-visible methods on the parent class, which may compromise security. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NonSynchronizedMethodOverridesSynchronizedMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NonSynchronizedMethodOverridesSynchronizedMethod.html index 981adf3b131f..cf6fe2447dea 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NonSynchronizedMethodOverridesSynchronizedMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NonSynchronizedMethodOverridesSynchronizedMethod.html @@ -2,6 +2,7 @@ This inspection reports non-synchronized methods overriding synchronized methods. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NonThreadSafeLazyInitialization.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NonThreadSafeLazyInitialization.html index 13e31fffd259..9ff1045d920b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NonThreadSafeLazyInitialization.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NonThreadSafeLazyInitialization.html @@ -3,13 +3,15 @@ This inspection reports static variables being lazily initialized in an non-thread-safe manner. Lazy initialization of static variables should be done in an appropriate synchronization construct, to prevent different threads from -performing conflicting initialization.
    +performing conflicting initialization. +

    If applicable, quick-fix is suggested which introduces static holder pattern described in http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom where the JVM guarantees thread-safety of such initializations. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NoopMethodInAbstractClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NoopMethodInAbstractClass.html index b677173d728e..a4c3718a0be7 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NoopMethodInAbstractClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NoopMethodInAbstractClass.html @@ -3,6 +3,7 @@ This inspection reports "no-op" methods in abstract classes. It is usually a better design to make such methods abstract themselves, so that classes which inherit the methods will not forget to provide their own implementations. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NotifyCalledOnCondition.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NotifyCalledOnCondition.html index 205f716d1216..41d79745f59e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NotifyCalledOnCondition.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NotifyCalledOnCondition.html @@ -5,6 +5,7 @@ or notifyAll() on an object of class java.util.concurrent.locks.Condition(). It is almost certain that signal() or signalAll() was intended instead. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NotifyNotInSynchronizedContext.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NotifyNotInSynchronizedContext.html index a164161b5305..9b2e6babddd0 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NotifyNotInSynchronizedContext.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NotifyNotInSynchronizedContext.html @@ -5,6 +5,7 @@ statement or synchronized method. Calling notify() on an object without holding a lock on that object will result in an IllegalMonitorStateException being thrown. Such a construct is not necessarily an error, as the necessary lock may be acquired before the containing method is called, but it's worth looking at. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NotifyWithoutCorrespondingWait.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NotifyWithoutCorrespondingWait.html index 5db2cd4943dc..526344b46649 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NotifyWithoutCorrespondingWait.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NotifyWithoutCorrespondingWait.html @@ -4,6 +4,7 @@ This inspection reports on any call to Object.notify() or Object.notifyAll() for which no call to a corresponding Object.wait() can be found. Only calls which target fields of the current class are reported by this inspection. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NullArgumentToVariableArgMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NullArgumentToVariableArgMethod.html index 3888e7dd31ba..97815383abba 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NullArgumentToVariableArgMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NullArgumentToVariableArgMethod.html @@ -4,6 +4,7 @@ This inspection reports any calls to a variable-argument method which has a n in the variable-argument position (e.g System.out.printf("%s", null) ). Such a null argument may be confusing, as it is not wrapped as a single-element array, as may be expected. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NullThrown.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NullThrown.html index ccef3a9d8fa5..e57019e627e5 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NullThrown.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NullThrown.html @@ -1,6 +1,7 @@ This inspection reports any null literals which are used as the argument for a throw statement. +

    New in 11, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NumberEquality.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NumberEquality.html index ef87f70b25e2..7029b1ebe814 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NumberEquality.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NumberEquality.html @@ -4,6 +4,7 @@ This inspection reports any use of == to test for Number equality, rather than the ".equals()" method. With auto-boxing it is easy to make the mistake of comparing two Integer (or other subclass of java.lang.Number) objects instead of two ints. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NumericToString.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NumericToString.html index b4aa34e36124..0733e2ef39a1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NumericToString.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NumericToString.html @@ -2,6 +2,7 @@ This inspection reports any call of toString() on numeric objects. Such calls are usually incorrect in an internationalized environment. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ObjectAllocationInLoop.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ObjectAllocationInLoop.html index 574544d52d1f..863013a939a5 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ObjectAllocationInLoop.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ObjectAllocationInLoop.html @@ -3,6 +3,7 @@ This inspection reports object or array allocation inside loops. While not necessarily a problem, object allocation inside loop is a great place to look for memory leaks and performance issues. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ObjectEquality.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ObjectEquality.html index d73ab2bbd2cd..21f9c35cb28a 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ObjectEquality.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ObjectEquality.html @@ -5,6 +5,7 @@ to test for Object equality, rather than the ".equals()" method. Note that comparison of Strings or Numbers using == is not reported by this inspection, nor is the comparison of an object to null using ==, or the comparison of two array objects. +

    Use the checkboxes below to indicate whether uses of == between objects of an enumerated type, class type or types with private constructors should be reported by this inspection. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ObjectEqualsNull.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ObjectEqualsNull.html index 166ad1fc87b2..bb919514e003 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ObjectEqualsNull.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ObjectEqualsNull.html @@ -2,6 +2,7 @@ This inspection reports on calls to .equals() which have null as an argument. The semantics of such calls are almost certainly not what was intended. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ObjectNotify.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ObjectNotify.html index c92c22a3d8ef..544e85d4ebf9 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ObjectNotify.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ObjectNotify.html @@ -2,6 +2,7 @@ This inspection reports any calls to notify(). While occasionally useful, in almost all cases notifyAll() is a better choice. See Doug Lea's Concurrent Programming in Java for a discussion. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ObjectToString.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ObjectToString.html index e4231b1e38ac..c10c3078af40 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ObjectToString.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ObjectToString.html @@ -5,6 +5,7 @@ which use the default implementation from java.lang.Object. The default implementation is rarely desired, but easy to use by accident. Calls to .toString() on objects of type java.lang.Object are ignored by this inspection. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ObsoleteCollection.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ObsoleteCollection.html index da339650dbfc..00eac3f50191 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ObsoleteCollection.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ObsoleteCollection.html @@ -4,6 +4,7 @@ This inspection reports any uses of java.util.Vector or java.util.Hashtable. While still supported, these classes were made obsolete by the JDK1.2 collection classes, and should probably not be used in new development. +

    Use the checkbox below to ignore any cases where the obsolete collections are used as an argument to a method or assigned to a variable that requires the obsolete type. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/OctalAndDecimalIntegersMixed.html b/plugins/InspectionGadgets/src/inspectionDescriptions/OctalAndDecimalIntegersMixed.html index 010ac28f1910..f0684b11303f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/OctalAndDecimalIntegersMixed.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/OctalAndDecimalIntegersMixed.html @@ -3,6 +3,7 @@ This inspection reports any use of both octal and decimal integers in an array initialization. This is often due to creating an array by copying a list of numbers into an array without noticing that some of them are zero-padded, and will thus be interpreted by the Java compiler as octal. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/OctalLiteral.html b/plugins/InspectionGadgets/src/inspectionDescriptions/OctalLiteral.html index dac98a54cb17..cea33e60be79 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/OctalLiteral.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/OctalLiteral.html @@ -2,6 +2,7 @@ This inspection reports octal integer literals. Some coding standards prohibit the use of octal literals, as they may be easily confused with decimal literals. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/OnDemandImport.html b/plugins/InspectionGadgets/src/inspectionDescriptions/OnDemandImport.html index 22d4c1d5bd36..074dbda8c4d2 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/OnDemandImport.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/OnDemandImport.html @@ -4,6 +4,7 @@ This inspection reports any import statements which cover entire packages Some coding standards prohibit such import statements. Since IDEA can automatically detect and fix such statements with its "Optimize Imports" command, this inspection is mostly useful for off-line reporting on code bases that you don't intend to change. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/OrredNotEqualExpression.html b/plugins/InspectionGadgets/src/inspectionDescriptions/OrredNotEqualExpression.html index 2d030e53e634..43811337b726 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/OrredNotEqualExpression.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/OrredNotEqualExpression.html @@ -4,6 +4,7 @@ This inspection highlights expressions where a reference is compared to a differ on either side of an or-expression. For example: x != a || x != b. Such expressions are always true, and a quickfix is available to change them to the correct x != a && x != b +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/OverloadedMethodsWithSameNumberOfParameters.html b/plugins/InspectionGadgets/src/inspectionDescriptions/OverloadedMethodsWithSameNumberOfParameters.html index d5fa4c36eb4b..919550ad55c7 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/OverloadedMethodsWithSameNumberOfParameters.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/OverloadedMethodsWithSameNumberOfParameters.html @@ -2,6 +2,7 @@ This inspection reports on cases where multiple methods of the same class are declared with the identical name and same number of parameters. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/OverloadedVarargsMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/OverloadedVarargsMethod.html index b9d77e2af6f8..5acc0cd3d663 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/OverloadedVarargsMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/OverloadedVarargsMethod.html @@ -3,6 +3,7 @@ This inspection reports vararg methods, when there are one or more other methods with the same name present in a class. Overloaded varargs methods can be very confusing, as it is often not clear which overloading gets called. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/OverlyComplexArithmeticExpression.html b/plugins/InspectionGadgets/src/inspectionDescriptions/OverlyComplexArithmeticExpression.html index 2a95224436a7..fff84f793dd2 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/OverlyComplexArithmeticExpression.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/OverlyComplexArithmeticExpression.html @@ -2,6 +2,7 @@ This inspection reports arithmetic expressions with too many terms. Such expressions may be confusing and bug-prone. +

    Use the field provided below to specify the maximum number of terms allowed in an arithmetic expression.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/OverlyComplexBooleanExpression.html b/plugins/InspectionGadgets/src/inspectionDescriptions/OverlyComplexBooleanExpression.html index 77728892aad3..da938e182400 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/OverlyComplexBooleanExpression.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/OverlyComplexBooleanExpression.html @@ -2,6 +2,7 @@ This inspection reports boolean expressions with too many terms. Such expressions may be confusing and bug-prone. +

    Use the field provided below to specify the maximum number of terms allowed in a boolean expression.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/OverlyLargePrimitiveArrayInitializer.html b/plugins/InspectionGadgets/src/inspectionDescriptions/OverlyLargePrimitiveArrayInitializer.html index ac68d935e70c..1a40375b569c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/OverlyLargePrimitiveArrayInitializer.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/OverlyLargePrimitiveArrayInitializer.html @@ -8,6 +8,7 @@ arrays which contain too many elements. Such initializers may result in overly l class files, as code must be generated to initialize each array element. In memory or bandwidth constrained environments, it may be more efficient to load large arrays of primitives from resource files. +

    Use the field below to specify the maximum number of elements to allow in primitive array initializers. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/OverlyStrongTypeCast.html b/plugins/InspectionGadgets/src/inspectionDescriptions/OverlyStrongTypeCast.html index e5851ac9e467..aae1069dc4cc 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/OverlyStrongTypeCast.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/OverlyStrongTypeCast.html @@ -5,6 +5,7 @@ casting an object to ArrayList when casting it to List would do just as well. Note: much like the Redundant type cast inspection, applying the fix for this inspection may change the semantics of your program, if you are intentionally using an overly strong cast to cause a ClassCastException to be generated. Use caution. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/OverridableMethodCallDuringObjectConstruction.html b/plugins/InspectionGadgets/src/inspectionDescriptions/OverridableMethodCallDuringObjectConstruction.html index 87eae0c1de43..aa7a4d30db6b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/OverridableMethodCallDuringObjectConstruction.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/OverridableMethodCallDuringObjectConstruction.html @@ -7,6 +7,7 @@ Methods are overridable if they are not declared final, static or private. Such calls may result in subtle bugs, as the object is not guaranteed to be initialized before the method call occurs. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/OverriddenMethodCallDuringObjectConstruction.html b/plugins/InspectionGadgets/src/inspectionDescriptions/OverriddenMethodCallDuringObjectConstruction.html index 2938e527c360..26636e4c6f19 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/OverriddenMethodCallDuringObjectConstruction.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/OverriddenMethodCallDuringObjectConstruction.html @@ -5,6 +5,7 @@ An object is constructed inside a constructor, an instance initializer or inside a clone(), readObject() or readObjectNoData() method. Such calls may result in subtle bugs, as the object is not guaranteed to be initialized before the method call occurs. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PackageDotHtmlMayBePackageInfo.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PackageDotHtmlMayBePackageInfo.html index 4f9309f2049c..a9cd6a95d22e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PackageDotHtmlMayBePackageInfo.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PackageDotHtmlMayBePackageInfo.html @@ -8,6 +8,7 @@ sole repository for package level annotations and documentation. This inspection provides a quickfix to convert the package.html file to a package-info.java file. If a package-info.java file is already present this inspection provides a quickfix to delete the package.html file, since the Javadoc tool would ignore it then anyway. +

    New in 10.0.3, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PackageInMultipleModules.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PackageInMultipleModules.html index dad9fe56431a..c0ebd48b5168 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PackageInMultipleModules.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PackageInMultipleModules.html @@ -2,6 +2,7 @@ This global inspection reports any packages which are present in multiple modules. Since this inspection requires global code analysis, it is only available in batch inspection mode. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PackageNamingConvention.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PackageNamingConvention.html index 221cacbb6427..9eddb8328048 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PackageNamingConvention.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PackageNamingConvention.html @@ -2,6 +2,7 @@ This global inspection reports packages whose names are either too short, too long, or do not follow the specified regular expression pattern. Since this inspection requires global code analysis, it is only available in batch inspection mode. +

    Use the fields provided below to specify minimum length, maximum length and regular expression expected for method parameter names (Regular expressions are in standard java.util.regex format). diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PackageVisibleField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PackageVisibleField.html index f1ccbc51447c..9a42703d1ddb 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PackageVisibleField.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PackageVisibleField.html @@ -2,6 +2,7 @@ This inspection reports package-visible instance variables. Constants (i.e. variables marked static and final) are not reported. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PackageVisibleInnerClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PackageVisibleInnerClass.html index 0bc5745096f5..1eaa1ad27225 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PackageVisibleInnerClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PackageVisibleInnerClass.html @@ -1,6 +1,7 @@ This inspection reports package-visible inner classes. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PackageWithTooFewClasses.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PackageWithTooFewClasses.html index 460cd9574cce..83df05e31bc4 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PackageWithTooFewClasses.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PackageWithTooFewClasses.html @@ -2,6 +2,7 @@ This global inspection reports any packages which contain too few classes. Overly small packages may indicate an overly fragmented design. +

    Use the field below to specify the minimum number of classes a package may have before triggering this inspection.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PackageWithTooManyClasses.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PackageWithTooManyClasses.html index ddc158a38f46..f93d3c6cb852 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PackageWithTooManyClasses.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PackageWithTooManyClasses.html @@ -3,6 +3,7 @@ This global inspection reports any packages which contain too many classes. Overly large packages may indicate a lack of design clarity. Since this inspection requires global code analysis, it is only available in batch inspection mode. +

    Use the field below to specify the maximum number of classes a package may have before triggering this inspection.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ParameterHidingMemberVariable.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ParameterHidingMemberVariable.html index f85cfa51f6ba..426ea49d5527 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ParameterHidingMemberVariable.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ParameterHidingMemberVariable.html @@ -2,6 +2,7 @@ This inspection reports method parameters being named identically to visible member variables of their class. Such a parameter name may be confusing. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ParameterNameDiffersFromOverriddenParameter.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ParameterNameDiffersFromOverriddenParameter.html index f8d3d04af271..67c2ecbdcef1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ParameterNameDiffersFromOverriddenParameter.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ParameterNameDiffersFromOverriddenParameter.html @@ -3,6 +3,7 @@ This inspection reports parameters that have different names from the corresponding parameters in the methods they override. While legal in Java, such inconsistent names may be confusing, and lessen the documentation benefits of good naming practices. +

    Use the checkboxes below to indicate whether overridden parameter names which are only a single character long or come from a library method should be ignored. Both can be useful if diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ParameterNamingConvention.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ParameterNamingConvention.html index 368b3272fbef..71c6bfb47aa5 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ParameterNamingConvention.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ParameterNamingConvention.html @@ -2,6 +2,7 @@ This inspection reports method parameters whose names are either too short, too long, or do not follow the specified regular expression pattern. +

    Use the fields provided below to specify minimum length, maximum length and regular expression expected for method parameter names. (Regular expressions are in standard java.util.regex format.) diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ParameterOfConcreteClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ParameterOfConcreteClass.html index 0c5ac50d1ebf..009dfbb1e660 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ParameterOfConcreteClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ParameterOfConcreteClass.html @@ -3,6 +3,7 @@ This inspection reports any method parameters whose type is declared to be a concrete class, rather than an interface. Such declarations may represent a failure of abstraction, and may make testing more difficult. Declarations whose classes come from system or third-party libraries will not be reported by this inspection. +

    Use the checkbox below to have this inspection ignore method parameters whose type is an abstract class.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ParameterizedParametersStaticCollection.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ParameterizedParametersStaticCollection.html index 390415bc3885..046607b20048 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ParameterizedParametersStaticCollection.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ParameterizedParametersStaticCollection.html @@ -2,6 +2,7 @@ This inspection reports classes annotated with @RunWith(Parameterized.class) without data provider method annotated with @Parameterized.Parameters +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ParametersPerConstructor.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ParametersPerConstructor.html index 6cb8c828ed22..4392ee862fc8 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ParametersPerConstructor.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ParametersPerConstructor.html @@ -2,6 +2,7 @@ This inspection reports constructors with too many parameters. Constructors with too many parameters can be a good sign that refactoring is necessary. +

    Use the field provided below to specify the maximum acceptable number of parameters a constructor might have.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ParametersPerMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ParametersPerMethod.html index a334dfea2a4e..c455163f1e4b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ParametersPerMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ParametersPerMethod.html @@ -3,6 +3,7 @@ This inspection reports methods with too many parameters. Methods with too many parameters can be a good sign that refactoring is necessary. Methods whose signatures are inherited from library classes are ignored by this inspection. +

    Use the field provided below to specify the maximum acceptable number of parameters a method might have.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PointlessArithmeticExpression.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PointlessArithmeticExpression.html index 73815b7f96dd..6dc234213990 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PointlessArithmeticExpression.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PointlessArithmeticExpression.html @@ -5,6 +5,7 @@ expressions. Such expressions include adding or subtracting zero, multiplying by division by one, and shift by zero. Such expressions may be the result of automated refactorings not completely followed through to completion, and in any case are unlikely to be what the developer intended to do. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PointlessBitwiseExpression.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PointlessBitwiseExpression.html index e4e50c5b59bf..6f7c65c3bb2b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PointlessBitwiseExpression.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PointlessBitwiseExpression.html @@ -5,6 +5,7 @@ expressions. Such expressions include anding with zero, oring by z and shift by zero. Such expressions may be the result of automated refactorings not completely followed through to completion, and in any case are unlikely to be what the developer intended to do. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PointlessBooleanExpression.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PointlessBooleanExpression.html index ec43f03ce111..0443701fa5da 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PointlessBooleanExpression.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PointlessBooleanExpression.html @@ -6,6 +6,7 @@ complicated boolean expressions. Such expressions include anding with tru equality comparison with a boolean literal, or negation of a boolean literal. Such expressions may be the result of automated refactorings not completely followed through to completion, and in any case are unlikely to be what the developer intended to do. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PointlessIndexOfComparison.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PointlessIndexOfComparison.html index 0382cc8c0ded..2c50ad9ae516 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PointlessIndexOfComparison.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PointlessIndexOfComparison.html @@ -3,6 +3,7 @@ This inspection reports pointless comparison with .indexOf() expression. An example of such an expression is comparing the result of .indexOf() with numbers less than -1. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PointlessNullCheck.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PointlessNullCheck.html index a5e68a905d33..5b77607bbbb0 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PointlessNullCheck.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PointlessNullCheck.html @@ -7,6 +7,7 @@ there is no need to also have a null check.

        if (x != null && x instanceof String) { ... }

    The quickfix changes this code to:

        if (x instanceof String) { ... }
    +

    New in 11, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PrimitiveArrayArgumentToVariableArgMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PrimitiveArrayArgumentToVariableArgMethod.html index 23b5c7b6628e..abe2cef1e89a 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PrimitiveArrayArgumentToVariableArgMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PrimitiveArrayArgumentToVariableArgMethod.html @@ -4,6 +4,7 @@ This inspection reports any calls to a variable-argument method which has a prim in the variable-argument position (e.g System.out.printf("%s", new int[]{1, 2, 3}) ). Such a primitive-array argument may be confusing, as it will wrapped as a single-element array, rather than each individual element being boxed, as might be expected. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PrivateMemberAccessBetweenOuterAndInnerClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PrivateMemberAccessBetweenOuterAndInnerClass.html index 515088764089..c630bf245ff9 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PrivateMemberAccessBetweenOuterAndInnerClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PrivateMemberAccessBetweenOuterAndInnerClass.html @@ -9,6 +9,7 @@ another class. To enable access from an inner class to private members of a containing class or the other way around javac and other compilers create package private synthetic accessor methods. Less use of memory and greater performance may be achieved by making the member package local, thus allowing direct access without the creation of synthetic accessor methods. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ProtectedField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ProtectedField.html index 5bb5f2b4e206..cab6de28fde4 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ProtectedField.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ProtectedField.html @@ -2,6 +2,7 @@ This inspection reports protected instance variables. Constants (i.e. variables marked static and final) are not reported. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ProtectedInnerClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ProtectedInnerClass.html index 62926409763e..56ece589029b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ProtectedInnerClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ProtectedInnerClass.html @@ -1,6 +1,7 @@ This inspection reports protected inner classes. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ProtectedMemberInFinalClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ProtectedMemberInFinalClass.html index 945483334810..503a18f64222 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ProtectedMemberInFinalClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ProtectedMemberInFinalClass.html @@ -3,6 +3,7 @@ This inspection reports members being declared protected in classes that are declared final. Such members may be declared private or package-visible instead. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PublicConstructorInNonPublicClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PublicConstructorInNonPublicClass.html index 26ed7c28a378..5dd636e833ae 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PublicConstructorInNonPublicClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PublicConstructorInNonPublicClass.html @@ -2,6 +2,7 @@ This inspection reports all constructors in non-public classes that are declared public. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PublicFieldAccessedInSynchronizedContext.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PublicFieldAccessedInSynchronizedContext.html index 8279fd5ff151..2baee0d9cdd4 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PublicFieldAccessedInSynchronizedContext.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PublicFieldAccessedInSynchronizedContext.html @@ -3,6 +3,7 @@ This inspection reports non-final, non-private fields which are accessed in a synchronized context. A non-private field cannot be guaranteed to always be accessed in a synchronized manner, and such "partially synchronized" access may result in unexpectedly inconsistent data structures. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PublicInnerClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PublicInnerClass.html index f0f488bfde3c..64fe53a42da1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PublicInnerClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PublicInnerClass.html @@ -1,6 +1,7 @@ This inspection reports public inner classes. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PublicStaticArrayField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PublicStaticArrayField.html index 1912174add86..9a3783f908cb 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PublicStaticArrayField.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PublicStaticArrayField.html @@ -3,6 +3,7 @@ This inspection reports public static array fields. Often used to store arrays of constant values, these fields nonetheless represent a security hazard, as their contents may be modified, even if the field is declared as final. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PublicStaticCollectionField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PublicStaticCollectionField.html index 407b6c54621b..b8f610e80bd6 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PublicStaticCollectionField.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PublicStaticCollectionField.html @@ -3,6 +3,7 @@ This inspection reports public static Collection fields. Often used to store collections of constant values, these fields nonetheless represent a security hazard, as their contents may be modified, even if the field is declared as final. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/QuestionableName.html b/plugins/InspectionGadgets/src/inspectionDescriptions/QuestionableName.html index 9a2a069fa56e..a13b58d41930 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/QuestionableName.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/QuestionableName.html @@ -3,6 +3,7 @@ This inspection reports on any variables, methods, or classes with questionable names. This inspection is best used to report common metasyntactic variables which may be used as names by lazy or confused developers. +

    Use the list below to specify names which should be reported

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/RandomDoubleForRandomInteger.html b/plugins/InspectionGadgets/src/inspectionDescriptions/RandomDoubleForRandomInteger.html index edced344fed2..d08457b29f8b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/RandomDoubleForRandomInteger.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/RandomDoubleForRandomInteger.html @@ -4,6 +4,7 @@ This inspection reports any calls to java.util.Random.getDouble() which are then multiplied by some factor and cast to an integer. For generating a random integer in some range, java.util.Random.getInt() is more efficient. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/RawUseOfParameterizedType.html b/plugins/InspectionGadgets/src/inspectionDescriptions/RawUseOfParameterizedType.html index caf58bb76d26..44180bcedf3d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/RawUseOfParameterizedType.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/RawUseOfParameterizedType.html @@ -4,13 +4,14 @@ This inspection reports any uses of parameterized classes where the type paramet Such "raw" uses of parameterized types are valid in Java, but defeat the purpose of using type parameters, and may mask bugs.

    +This inspection only reports if the project or module is configured to use a +language level of 5.0 or higher. + +

    Use the first checkbox below to ignore the construction of objects of parameterized types. Use the second checkbox below to ignore raw types in type casts.

    -This inspection only reports if the project or module is configured to use a -language level of 5.0 or higher. -

    Powered by InspectionGadgets \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ReadObjectAndWriteObjectPrivate.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ReadObjectAndWriteObjectPrivate.html index 484a32d7ef0c..8931c49814a8 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ReadObjectAndWriteObjectPrivate.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ReadObjectAndWriteObjectPrivate.html @@ -3,6 +3,7 @@ This inspection reports Serializable classes where the readObject and writeObject() methods are not declared private. There is no reason these methods should ever have greater visibility than that. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ReadObjectInitialization.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ReadObjectInitialization.html index c93921219d4d..3042cd790032 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ReadObjectInitialization.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ReadObjectInitialization.html @@ -5,6 +5,7 @@ deserialized by the readObject() method.

    Note: This inspection uses a very conservative dataflow algorithm, and may report instance variables as uninitialized incorrectly. Variables reported as initialized will always be initialized. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ReadResolveAndWriteReplaceProtected.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ReadResolveAndWriteReplaceProtected.html index d50f4d24e3c2..d47e9014e48f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ReadResolveAndWriteReplaceProtected.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ReadResolveAndWriteReplaceProtected.html @@ -4,6 +4,7 @@ This inspection reports Serializable classes where the readResolve()writeReplace() methods are not declared protected. Note: in the case of classes declared final, these methods may be declared private, instead. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/RecordStoreResource.html b/plugins/InspectionGadgets/src/inspectionDescriptions/RecordStoreResource.html index b67228b001be..94abb12e4c93 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/RecordStoreResource.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/RecordStoreResource.html @@ -6,6 +6,7 @@ Applying the results of this inspection without consideration might have negativ This inspection reports any J2ME RecordStore resource which is not opened in front of a try block and closed in the corresponding finally block. Such resources may be inadvertently leaked if an exception is thrown before the resource is closed. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantFieldInitialization.html b/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantFieldInitialization.html index dcd2209f7102..a76161ac0115 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantFieldInitialization.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantFieldInitialization.html @@ -2,6 +2,7 @@ This inspection reports fields explicitly initialized to the same values that the JVM would initialize them to by default. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantImplements.html b/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantImplements.html index a89b2d5b570f..472712c9fb1d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantImplements.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantImplements.html @@ -3,6 +3,7 @@ This inspection reports any cases of classes declaring that they implement or extend an interface, when that interface is already declared as implemented by a superclass or extended by another interface of that class. Such declarations are unnecessary, and may be safely removed. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantImport.html b/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantImport.html index 38fe990693cb..ad434d6297e6 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantImport.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantImport.html @@ -5,6 +5,7 @@ statements that are covered by previous import statements in the same file. Since IDEA can automatically detect and fix such statements with its "Optimize Imports" command, this inspection is mostly useful for off-line reporting on code bases that you don't intend to change. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantMethodOverride.html b/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantMethodOverride.html index 4380c0fe00b1..412669d55599 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantMethodOverride.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantMethodOverride.html @@ -2,6 +2,7 @@ This inspection reports any method that has a body and signature that are identical to its super method. Such a method is redundant and probably a coding error. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantStringFormatCall.html b/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantStringFormatCall.html index c8ce59ee9a0d..b45db25c9624 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantStringFormatCall.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantStringFormatCall.html @@ -3,6 +3,7 @@ This inspection reports any calls to String.format() where only a format string is provided, but no arguments. Such a call is unnecessary and can be replaced with just the string. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ReflectionForUnavailableAnnotation.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ReflectionForUnavailableAnnotation.html index 2b9363739408..3ecca5ce1f91 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ReflectionForUnavailableAnnotation.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ReflectionForUnavailableAnnotation.html @@ -5,6 +5,7 @@ annotation which is not defined has being retained at runtime. Using Class.isAnnotationPresent() to test for an annotation which has source retention or class-file retention (the default) will always result in a negative result, but is easy to do inadvertently. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/RefusedBequest.html b/plugins/InspectionGadgets/src/inspectionDescriptions/RefusedBequest.html index c1dd76007908..a0d6535808ef 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/RefusedBequest.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/RefusedBequest.html @@ -4,6 +4,7 @@ This inspection reports any methods which override concrete methods, but which do not call that method as super. Such methods may represent a failure of abstraction, and can lead to hard-to-trace bugs. Methods overridden from java.lang.Object are not reported by this inspection. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ReplaceAllDot.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ReplaceAllDot.html index c251bd994a48..fd64a95ba235 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ReplaceAllDot.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ReplaceAllDot.html @@ -5,6 +5,7 @@ This inspection reports any calls to as the first argument. Calling replaceAll(".", ...) replaces all of the characters in a string with its second argument, which is rarely the desired functionality. More probably, replaceAll("\.", ...) was intended. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ReplaceAssignmentWithOperatorAssignment.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ReplaceAssignmentWithOperatorAssignment.html index 3ffb594b8159..825f489c14ee 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ReplaceAssignmentWithOperatorAssignment.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ReplaceAssignmentWithOperatorAssignment.html @@ -2,6 +2,7 @@ This inspection reports assignment operations which can be replaced by operator-assignment. Code using operator assignment may be clearer, and theoretically more performant. +

    Use the check box below to ignore the conditional operators && and ||. Replacing conditional operators with operator diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ResultOfObjectAllocationIgnored.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ResultOfObjectAllocationIgnored.html index 9da57f8e840a..06a0fc08ef36 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ResultOfObjectAllocationIgnored.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ResultOfObjectAllocationIgnored.html @@ -3,6 +3,7 @@ This inspection reports object allocation where the object allocated ignored. Such allocation expressions are legal Java, but are usually either inadvertent, or evidence of a very odd object initialization strategy. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ResultSetIndexZero.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ResultSetIndexZero.html index 30f9a01422b8..9be24484fc78 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ResultSetIndexZero.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ResultSetIndexZero.html @@ -3,6 +3,7 @@ This inspection reports any attempts to access column 0 of a java.sql.ResultSet or java.sql.PreparedStatement. For historical reasons columns of java.sql.ResultSets and java.sql.PreparedStatements are numbered beginning with 1, rather than 0, and accessing column 0 is a common error in JDBC programming. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ReturnFromFinallyBlock.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ReturnFromFinallyBlock.html index 1befcfed5ecc..5559c007b739 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ReturnFromFinallyBlock.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ReturnFromFinallyBlock.html @@ -3,6 +3,7 @@ This inspection reports return statements inside of finally blocks. While occasionally intended, such return statements may mask exceptions thrown, and tremendously complicate debugging. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ReturnNull.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ReturnNull.html index 9d543b953b86..05248859bbf1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ReturnNull.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ReturnNull.html @@ -4,6 +4,7 @@ This inspection reports return statements with null values. While occasionally useful, this construct may make the code more prone to failing with a NullPointerException, and often indicates that the developer doesn't really understand the classes intended semantics. +

    Use the first control below to let this inspection ignore private methods.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ReturnOfCollectionField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ReturnOfCollectionField.html index d23718eec458..57bbcf480ba6 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ReturnOfCollectionField.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ReturnOfCollectionField.html @@ -4,6 +4,7 @@ This inspection reports any attempt to return an array or Collection fiel the array or Collection may have its contents modified by the calling method, this construct may result in an object having its state modified unexpectedly. While occasionally useful for performance reasons, this construct is inherently bug-prone. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ReturnOfDateField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ReturnOfDateField.html index cd9efbd70924..699a29e7772f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ReturnOfDateField.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ReturnOfDateField.html @@ -6,6 +6,7 @@ This inspection reports any attempt to return a java.lang.Date or treated as immutable values but are actually mutable, this construct may result in an object having its state modified unexpectedly. While occasionally useful for performance reasons, this construct is inherently bug-prone. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ReturnThis.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ReturnThis.html index 93c910e813e9..584740ea0a23 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ReturnThis.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ReturnThis.html @@ -4,6 +4,7 @@ This inspection reports methods returning this. While such a return is valid, it is rarely necessary, and usually indicates that the developer intends the method to be used as part of a chain of similar method calls (e.g. buffer.append("foo").append("bar").append("baz")). Such chains are frowned upon by many coding standards. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ReuseOfLocalVariable.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ReuseOfLocalVariable.html index 4453a30e2b5b..d8fd9f249af9 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ReuseOfLocalVariable.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ReuseOfLocalVariable.html @@ -6,6 +6,7 @@ as the intended semantics of the local variable may vary with each use. It may a prone to bugs, if code changes result in values that were thought to be overwritten actually being live. It is good practices to keep variable lifetimes as short as possible, and not reuse local variables for the sake of brevity. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/RuntimeExec.html b/plugins/InspectionGadgets/src/inspectionDescriptions/RuntimeExec.html index 1b73c555e2a3..a519e2ded993 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/RuntimeExec.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/RuntimeExec.html @@ -3,6 +3,7 @@ This inspection reports the calls to Runtime.exec() or any of its variants. Calls to Runtime.exec() are inherently unportable between operating systems. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/RuntimeExecWithNonConstantString.html b/plugins/InspectionGadgets/src/inspectionDescriptions/RuntimeExecWithNonConstantString.html index dd1fcd123b85..5257c6e8acc4 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/RuntimeExecWithNonConstantString.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/RuntimeExecWithNonConstantString.html @@ -3,6 +3,7 @@ This inspection reports the calls to Runtime.exec() or any of its variants which take a dynamically-constructed string as the statement to execute. Constructed execution strings are a common source of security breaches. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SafeLock.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SafeLock.html index 1bb1208abd0f..b2911623d4bb 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SafeLock.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SafeLock.html @@ -3,6 +3,7 @@ This inspection reports any java.util.concurrent.locks.Lock resource which is not acquired in front of a try block and unlocked in the corresponding finally block. Such resources may be inadvertently leaked if an exception is thrown before the resource is closed. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SamePackageImport.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SamePackageImport.html index a0417ba8c7ac..9a97a36b3c13 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SamePackageImport.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SamePackageImport.html @@ -5,6 +5,7 @@ containing file. Such imports are unnecessary, and probably the result of incomp refactorings. Since IDEA can automatically detect and fix such statements with its "Optimize Imports" command, this inspection is mostly useful for off-line reporting on code bases that you don't intend to change. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SerialPersistentFieldsWithWrongSignature.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SerialPersistentFieldsWithWrongSignature.html index c26ece932644..6b579c27426e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SerialPersistentFieldsWithWrongSignature.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SerialPersistentFieldsWithWrongSignature.html @@ -2,6 +2,7 @@ This inspection reports Serializable classes whose serialPersistentFields field. is not declared private static final ObjectStreamField. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SerialVersionUIDNotStaticFinal.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SerialVersionUIDNotStaticFinal.html index 0164db2cbf83..c95a5c89d28d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SerialVersionUIDNotStaticFinal.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SerialVersionUIDNotStaticFinal.html @@ -2,6 +2,7 @@ This inspection reports Serializable classes whose serialVersionUID field. is not declared private static final long. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableClassInSecureContext.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableClassInSecureContext.html index 589485e27e1b..1a03acfc8dd3 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableClassInSecureContext.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableClassInSecureContext.html @@ -4,6 +4,7 @@ This inspection reports classes which may be serialized. A class may be serialized if it supports the Serializable interface, and its writeObject() method is not defined to immediately throw an error. Serializable classes may be dangerous in code intended for secure use. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableHasSerialVersionUIDField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableHasSerialVersionUIDField.html index f6b2fab0263b..98c6f9a8e73e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableHasSerialVersionUIDField.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableHasSerialVersionUIDField.html @@ -2,6 +2,7 @@ This inspection reports any Serializable classes which do not provide a serialVersionUID field. Without a serialVersionUID field, any change to a class will make previously serialized versions unreadable. +

    Use the table below to specify what specific classes and inheritors should be excluded from being checked by this inspection. This is meant for those classes which, although they inherit diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableHasSerializationMethods.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableHasSerializationMethods.html index 206cb0ab664b..7d7ab80c96d7 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableHasSerializationMethods.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableHasSerializationMethods.html @@ -6,6 +6,7 @@ which do not provide readObject and and writeObject methods are not provided, the default serialization algorithms are used, which may be sub-optimal in many environments for performance and compatibility purposes. +

    Use the table below to specify what specific classes and inheritors should be excluded from being checked by this inspection. This is meant for those classes which, although they inherit diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableInnerClassHasSerialVersionUIDField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableInnerClassHasSerialVersionUIDField.html index 1464d91721f8..f00a3c9356b2 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableInnerClassHasSerialVersionUIDField.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableInnerClassHasSerialVersionUIDField.html @@ -7,6 +7,7 @@ It is strongly recommended that Serializable non-static inner classes hav a serialVersionUID field, otherwise the default serialization algorithm may result in serialized versions being incompatible between compilers, due to differences in synthetic accessor methods. +

    Use the table below to specify what specific classes and inheritors should be excluded from being checked by this inspection. This is meant for those classes which, although they inherit diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableInnerClassWithNonSerializableOuterClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableInnerClassWithNonSerializableOuterClass.html index abc1872cfe2d..7d7e455f17a1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableInnerClassWithNonSerializableOuterClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableInnerClassWithNonSerializableOuterClass.html @@ -3,6 +3,7 @@ This inspection reports Serializable non-static inner classes whose outer classes are non-Serializable. Such classes are unlikely to serialize correctly, due to implicit references from the inner to outer class. +

    Use the table below to specify what specific classes and inheritors should be excluded from being checked by this inspection. This is meant for those classes which, although they inherit diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableWithUnconstructableAncestor.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableWithUnconstructableAncestor.html index f2fb24c69e12..847af16e497d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableWithUnconstructableAncestor.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SerializableWithUnconstructableAncestor.html @@ -2,6 +2,7 @@ This inspection reports Serializable classes whose closest non-serializable ancestor lacks a no-argument constructor. Such classes can not be deserialized. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SetReplaceableByEnumSet.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SetReplaceableByEnumSet.html index 11e4d217db8c..25ee2c561c5a 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SetReplaceableByEnumSet.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SetReplaceableByEnumSet.html @@ -5,6 +5,7 @@ whose content types are enumerated classes. Such java.util.Set objects can be replaced by java.util.EnumSet objects. java.util.EnumSet implementations can be much more efficient that those of other sets, as the underlying data structure is a simple bitmap. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SetupCallsSuperSetup.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SetupCallsSuperSetup.html index f76131a3bf28..44e229245746 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SetupCallsSuperSetup.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SetupCallsSuperSetup.html @@ -2,6 +2,7 @@ This inspection reports JUnit classes whose setUp() method does not call super.setUp(). +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SetupIsPublicVoidNoArg.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SetupIsPublicVoidNoArg.html index e388171147ef..82b89f78004d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SetupIsPublicVoidNoArg.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SetupIsPublicVoidNoArg.html @@ -5,6 +5,7 @@ is not declared public, does not return void, or takes arguments. Such setUp() methods are easy to create inadvertently, and will not be executed by JUnit tests runners. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ShiftOutOfRange.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ShiftOutOfRange.html index 51408d0e4145..6bc38d15c2d5 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ShiftOutOfRange.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ShiftOutOfRange.html @@ -5,6 +5,7 @@ where the value shifted by is constant and outside of the reasonable range. Inte shift operations outside of the range 0..31 and long shift operations outside of the range 0..63 are reported. Shifting by negative or overly large values is almost certainly a coding error. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SignalWithoutCorrespondingAwait.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SignalWithoutCorrespondingAwait.html index 721ffcb429db..484570eb4cf1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SignalWithoutCorrespondingAwait.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SignalWithoutCorrespondingAwait.html @@ -4,6 +4,7 @@ This inspection reports on any call to Condition.signal() or Condition.signalAll() for which no call to a corresponding Condition.await() can be found. Only calls which target fields of the current class are reported by this inspection. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SimpleDateFormatWithoutLocale.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SimpleDateFormatWithoutLocale.html index f828d6652904..3a04be138489 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SimpleDateFormatWithoutLocale.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SimpleDateFormatWithoutLocale.html @@ -3,6 +3,7 @@ This inspection reports any instantiations of java.util.SimpleDateFormat which do not specify a java.util.Locale. Such calls are usually incorrect in an internationalized environment. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SimplifiableAnnotation.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SimplifiableAnnotation.html index 38b21c56e75b..1905b0839765 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SimplifiableAnnotation.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SimplifiableAnnotation.html @@ -3,6 +3,7 @@ This inspection reports annotations which can be simplified to their 'single element' or 'marker' shorthand form. Annotations that contain whitespace between the @-sign and the name of the annotation are also reported. +

    New in 10, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SimplifiableConditionalExpression.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SimplifiableConditionalExpression.html index b270d7afdb0e..b6ac1d0aa8e4 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SimplifiableConditionalExpression.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SimplifiableConditionalExpression.html @@ -6,6 +6,7 @@ This inspection reports conditional expressions of the form expressions may be safely simplified to condition || foo or !condition && foo, respectively. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SimplifiableEqualsExpression.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SimplifiableEqualsExpression.html index 7835902c93e8..b876cdd52da6 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SimplifiableEqualsExpression.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SimplifiableEqualsExpression.html @@ -11,6 +11,7 @@ And the quickfix will replace that with:

         if ("literal".equals(s)) {}
     
    +

    New in 11, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SimplifiableIfStatement.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SimplifiableIfStatement.html index 98a74c0f1e31..ade84e02d39d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SimplifiableIfStatement.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SimplifiableIfStatement.html @@ -9,6 +9,7 @@ or if (condition) return false else return foo. These expressions may be safely simplified to return condition && foo or return !condition || foo, respectively. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SimplifiableJUnitAssertion.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SimplifiableJUnitAssertion.html index 95d1af0a67fb..85aa65d10f40 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SimplifiableJUnitAssertion.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SimplifiableJUnitAssertion.html @@ -3,6 +3,7 @@ This inspection reports any JUnit assertTrue calls which can be replaced by equivalent assertEquals calls. assertEquals calls will normally give better error messages in case of test failure than assertTrue can. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SingleCharacterStartsWith.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SingleCharacterStartsWith.html index 3ce3f8b50ccb..978c207d876c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SingleCharacterStartsWith.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SingleCharacterStartsWith.html @@ -9,6 +9,7 @@ literals as parameter. Such calls may be more efficiently implemented with String.charAt(). Because the performance gain is minimal, the needed extra check for non-zero length, and the negative effect on code clarity, it is recommended to do so only inside tight loops. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SingleClassImport.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SingleClassImport.html index 47d84f2e63ca..06cb04422cfd 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SingleClassImport.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SingleClassImport.html @@ -4,6 +4,7 @@ This inspection reports any import statements which cover single classes Some coding standards prohibit such import statements. Since IDEA can automatically detect and fix such statements with its "Optimize Imports" command, this inspection is mostly useful for off-line reporting on code bases that you don't intend to change. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/Singleton.html b/plugins/InspectionGadgets/src/inspectionDescriptions/Singleton.html index d63645451808..910eefa65f15 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/Singleton.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/Singleton.html @@ -4,6 +4,7 @@ This inspection reports singleton classes. Singleton classes are declared so that only one instance of the class may ever be instantiated. Singleton classes complicate testing, and their presence may indicate a lack of object-oriented design. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SizeReplaceableByIsEmpty.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SizeReplaceableByIsEmpty.html index 1c8ea9741f82..6788578061bd 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SizeReplaceableByIsEmpty.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SizeReplaceableByIsEmpty.html @@ -2,6 +2,7 @@ This inspection reports any .size() or .length() comparisons with a 0 literal which can be replaced with a call to .isEmpty(). +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SleepWhileHoldingLock.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SleepWhileHoldingLock.html index 1e248e510193..6c941ec7e9c0 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SleepWhileHoldingLock.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SleepWhileHoldingLock.html @@ -5,6 +5,7 @@ within a synchronized block or method. Sleeping while synchronized may result in decreased performance, poor scalability, and possibly even deadlocking. Consider using wait instead, as it will release the lock held. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SocketResource.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SocketResource.html index a8560ab0caad..6a061f63a3bb 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SocketResource.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SocketResource.html @@ -7,6 +7,7 @@ be inadvertently leaked if an exception is thrown before the resource is closed. by this inspection include java.net.Socket, java.net.DatagramSocket, and java.net.ServerSocket. +

    Use the checkbox below to specify if a Socket is allowed to be opened inside a try block. This style is less desirable because it is more verbose than opening a Socket diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StandardVariableNames.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StandardVariableNames.html index 3ccf2cd7298d..c615ae93be69 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StandardVariableNames.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StandardVariableNames.html @@ -11,6 +11,7 @@ Such names may be confusing. Standard names and types are as follows:

  • l - long
  • s, str - String
  • +

    Use the checkbox below to ignore parameter names which are identical to the parameter name from a direct super method. Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticCallOnSubclass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticCallOnSubclass.html index 07023fb9fd4c..5f4e5ff342ed 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticCallOnSubclass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticCallOnSubclass.html @@ -4,6 +4,7 @@ This inspection reports static method calls where the call is qualified by a subclass of the declaring class, rather than the declaring class itself (e.g. MyThreadSubclass.sleep()). Java allows such qualification, but such calls may be confusing, and may indicate a subtle confusion of inheritance and overriding. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticCollection.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticCollection.html index 60ed3fcaea8d..41921649de4e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticCollection.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticCollection.html @@ -3,6 +3,7 @@ This inspection reports Collection variables declared as static. While not necessarily a problem, static collections are often causes of memory leaks, and are therefore prohibited by some coding standards. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticFieldCanBeMovedToUse.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticFieldCanBeMovedToUse.html index dcc8d9aab481..2d2f885e701f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticFieldCanBeMovedToUse.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticFieldCanBeMovedToUse.html @@ -3,6 +3,7 @@ This global inspection reports any static fields which are only used in a different class than the one they are defined in. Such fields can be moved. Since this inspection requires global code analysis, it is only available in batch inspection mode. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticFieldReferenceOnSubclass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticFieldReferenceOnSubclass.html index 5118f47ceda9..00cee37e2d7a 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticFieldReferenceOnSubclass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticFieldReferenceOnSubclass.html @@ -4,6 +4,7 @@ This inspection reports static field access where the call is qualified by a subclass of the declaring class, rather than the declaring class itself. Java allows such qualification, but such accesses may be confusing, and may indicate a subtle confusion of inheritance and overriding. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticImport.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticImport.html index 1eecbe42bd11..570e5de1c36f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticImport.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticImport.html @@ -2,6 +2,7 @@ This inspection reports static import statements. Such import statements are not supported under Java 1.4 or earlier JVMs. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticInheritance.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticInheritance.html index e365fdc35bfe..584d7bf70cd3 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticInheritance.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticInheritance.html @@ -3,6 +3,7 @@ This inspection reports interfaces which are implemented for no reason other than access to constants. Such inheritance is often confusing, and may hide important dependency information. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticMethodNamingConvention.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticMethodNamingConvention.html index 3cf6c6ddbb34..e9cd6fa73d22 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticMethodNamingConvention.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticMethodNamingConvention.html @@ -2,6 +2,7 @@ This inspection reports static methods whose names are either too short, too long, or do not follow the specified regular expression pattern. +

    Use the fields provided below to specify minimum length, maximum length and regular expression expected for static method names. (Regular expressions are in standard java.util.regex format.) diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticMethodOnlyUsedInOneClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticMethodOnlyUsedInOneClass.html index 601cbe807c7c..c252440e5e80 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticMethodOnlyUsedInOneClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticMethodOnlyUsedInOneClass.html @@ -5,6 +5,7 @@ are only called from one class which is not the same as the class containing the method. Such methods could be moved into that class.

    This inspection may be cpu intensive. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticNonFinalField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticNonFinalField.html index cbf576891e2d..861a000c5955 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticNonFinalField.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticNonFinalField.html @@ -1,6 +1,7 @@ This inspection reports non-final static fields. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticSuite.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticSuite.html index 172a323b16ed..c6c8a287733e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticSuite.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticSuite.html @@ -2,6 +2,7 @@ This inspection reports JUnit test case classes which contain suite() methods which are not declared static. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticVariableInitialization.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticVariableInitialization.html index d4cc0bd79d8e..1000f1b78a61 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticVariableInitialization.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticVariableInitialization.html @@ -2,10 +2,11 @@ This inspection reports static variables which are not guaranteed to be initialized upon class initialization.

    -Use the checkbox below to indicate whether you want uninitialized primitive fields to be reported. -

    Note: This inspection uses a very conservative dataflow algorithm, and may report static variables as uninitialized incorrectly. Variables reported as initialized will always be initialized. + +

    + Use the checkbox below to indicate whether you want uninitialized primitive fields to be reported.

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticVariableNamingConvention.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticVariableNamingConvention.html index 777b815b7470..625244614fe5 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticVariableNamingConvention.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticVariableNamingConvention.html @@ -3,6 +3,7 @@ This inspection reports static variables whose names are either too short, too long, or do not follow the specified regular expression pattern. Constants, i.e. variables of immutable type declared static final, are not checked by this inspection +

    Use the fields provided below to specify minimum length, maximum length and regular expression expected for static variable names. (Regular expressions are in standard java.util.regex format.) diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticVariableOfConcreteClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticVariableOfConcreteClass.html index e43d9214952d..e8ea4b76c4db 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticVariableOfConcreteClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticVariableOfConcreteClass.html @@ -3,6 +3,7 @@ This inspection reports any static fields whose type is declared to be a concrete class, rather than an interface. Such declarations may represent a failure of abstraction, and may make testing more difficult. Declarations whose classes come from system or third-party libraries will not be reported by this inspection. +

    Use the checkbox below to have this inspection ignore static fields whose type is an abstract class.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticVariableUninitializedUse.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticVariableUninitializedUse.html index 4a5459bb4f78..223d25c1b85e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StaticVariableUninitializedUse.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StaticVariableUninitializedUse.html @@ -2,10 +2,11 @@ This inspection reports static variables which are read prior to initialization.

    -Use the checkbox below to indicate whether you want uninitialized primitive fields to be reported. -

    Note: This inspection uses a very conservative dataflow algorithm, and may report static variables used uninitialized incorrectly. Variables reported as initialized will always be initialized. + +

    +Use the checkbox below to indicate whether you want uninitialized primitive fields to be reported.

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferField.html index 13e072421c3e..ecdd35ec0a8f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferField.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferField.html @@ -4,6 +4,7 @@ This inspection reports fields with type java.lang.StringBuffer or java.lang.StringBuilder. StringBuffer fields can grow without limit, and are often the cause of memory leaks. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferMustHaveInitialCapacity.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferMustHaveInitialCapacity.html index a10acd561dc4..0c738998be77 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferMustHaveInitialCapacity.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferMustHaveInitialCapacity.html @@ -5,6 +5,7 @@ This inspection reports any attempt to instantiate a new StringBuffer or If no initial capacity is specified, a default capacity is used, which will rarely be optimal. Failing to specify initial capacities for StringBuffers may result in performance issues, if space needs to be reallocated and memory copied when capacity is exceeded +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferReplaceableByString.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferReplaceableByString.html index 832b4e495ec3..dc144db4b2e6 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferReplaceableByString.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferReplaceableByString.html @@ -3,6 +3,7 @@ This inspection reports any variables declared as or uses of java.lang.StringBuffer and java.lang.StringBuilder which are effectively constant. These may be replaced with java.lang.String expressions which results in simpler and possibly more efficient code. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferReplaceableByStringBuilder.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferReplaceableByStringBuilder.html index 8571cdbef2be..6f5c47c3851b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferReplaceableByStringBuilder.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferReplaceableByStringBuilder.html @@ -7,6 +7,7 @@ more efficiently declared as java.lang.StringBuilder.

    This inspection only reports if the project or module is configured to use a language level of 5.0 or higher. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferToStringInConcatenation.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferToStringInConcatenation.html index d670ac9c333d..d488b4ded5ba 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferToStringInConcatenation.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferToStringInConcatenation.html @@ -4,6 +4,7 @@ This inspection reports StringBuffer.toString() or StringBuilder.toString() in String concatenations. In addition to being confusing, this code performs String allocation and copying, which is unnecessary as of JDK1.4. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringCompareTo.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringCompareTo.html index f7dff9c6c3df..198717d87fc5 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StringCompareTo.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringCompareTo.html @@ -2,6 +2,7 @@ This inspection reports any call of compareTo() on String objects. Such calls are usually incorrect in an internationalized environment. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenation.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenation.html index 16c3ef44ad6f..c825f2d5331c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenation.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenation.html @@ -3,18 +3,24 @@ This inspection reports any String concatenation (+). Concatenation is usually incorrect in an internationalized environment, and should be replace by uses of java.text.MessageFormat or similar classes. +

    Use the first checkbox below to have this inspection ignore string concatenations which are used as a description argument in an assert statement. -
    Use the second checkbox to ignore string concatenations used as arguments +

    +Use the second checkbox to ignore string concatenations used as arguments for a call to any of the System.out.print() methods. -
    Use the third checkbox to ignore string concatenations used as arguments +

    +Use the third checkbox to ignore string concatenations used as arguments for a call to any of the System.err.print() methods. -
    Use the fourth checkbox to ignore string concatenations used as arguments in +

    +Use the fourth checkbox to ignore string concatenations used as arguments in the construction of any subclass of java.lang.Throwable -
    Use the fifth checkbox to ignore string concatenations in the initializers +

    +Use the fifth checkbox to ignore string concatenations in the initializers of constant fields. -
    Use the sixth checkbox to ignore string concatenations in test code. +

    +Use the sixth checkbox to ignore string concatenations in test code.

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenationInFormatCall.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenationInFormatCall.html index d2f1e841bb5e..ab7286fb909a 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenationInFormatCall.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenationInFormatCall.html @@ -8,6 +8,7 @@ This inspection checks calls to appropriate methods on java.lang.String, java.io.PrintWriter, or java.io.PrintStream. +

    New in 10.0.2, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenationInLoops.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenationInLoops.html index 383f6baab816..837deab0bf72 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenationInLoops.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenationInLoops.html @@ -4,6 +4,7 @@ This inspection reports String concatenation in loops. For performance reasons, is preferable to replace such concatenation with explicit calls to StringBuilder.append() or StringBuffer.append() +

    Use the checkbox below to indicate that this inspection should only warn when the same variable is appended to inside the loop. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenationInMessageFormatCall.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenationInMessageFormatCall.html index b45fe64e0568..7e51011b40a4 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenationInMessageFormatCall.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenationInMessageFormatCall.html @@ -4,6 +4,7 @@ This inspection reports non-constant string concatenations used as an argument t MessageFormat.format(). Often this is the result of mistakenly concatenating a string format argument by typing a '+' when a ',' was meant. +

    New in 10.0.2, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenationInsideStringBufferAppend.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenationInsideStringBufferAppend.html index e7eb51399621..c4e15b8f2bdd 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenationInsideStringBufferAppend.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringConcatenationInsideStringBufferAppend.html @@ -7,9 +7,12 @@ the argument to StringBuffer.append(), may profitably be turned into chained append calls on the existing StringBuffer/Builder/Appendable, saving the cost of an extra StringBuffer/Builder -allocation.
    This inspection ignores compile time evaluated String +allocation. +

    +This inspection ignores compile time evaluated String concatenations, which when converted to chained append calls would only worsen performance. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringConstructor.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringConstructor.html index f275db0d7b54..61b4fe84e9ff 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StringConstructor.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringConstructor.html @@ -4,6 +4,7 @@ This inspection reports any attempt to instantiate a new String object by copying an existing string. Constructing new String objects in this way is rarely necessary, and may cause performance problems if done often enough. +

    Use the check box below to ignore String constructor calls which have a String.substring() diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringEquality.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringEquality.html index 16244e4cae09..b968cac2eebb 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StringEquality.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringEquality.html @@ -2,6 +2,7 @@ This inspection reports any use of == to test for String equality, rather than the ".equals()" method. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringEquals.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringEquals.html index 4f08aaf20769..8552c148d583 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StringEquals.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringEquals.html @@ -2,6 +2,7 @@ This inspection reports any call of equals() on String objects. Such calls are usually incorrect in an internationalized environment. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringEqualsEmptyString.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringEqualsEmptyString.html index 282f688e5866..6e6f1bb37d83 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StringEqualsEmptyString.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringEqualsEmptyString.html @@ -3,6 +3,7 @@ This inspection reports .equals() being called to compare a String with an empty string. It is normally more performant to test a String for emptiness by comparing its .length() to zero instead. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringEqualsIgnoreCase.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringEqualsIgnoreCase.html index ae9299859a42..54abb65ff336 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StringEqualsIgnoreCase.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringEqualsIgnoreCase.html @@ -2,6 +2,7 @@ This inspection reports any call of equalsIgnoreCase() on String objects. Such calls are usually incorrect in an internationalized environment. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringReplaceableByStringBuffer.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringReplaceableByStringBuffer.html index f32e4fb480e3..2279743d56d0 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StringReplaceableByStringBuffer.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringReplaceableByStringBuffer.html @@ -2,7 +2,9 @@ This inspection reports any variables declared as java.lang.String which are repeatedly appended to. Such variables may be more efficiently declared as java.lang.StringBuffer -or java.lang.StringBuilder.
    +or java.lang.StringBuilder. + +

    Use the check box below to specify that this inspection should only warn when the variable is appended to in a loop.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringToString.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringToString.html index c7363451aa5f..b8f78a87b1c6 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StringToString.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringToString.html @@ -2,6 +2,7 @@ This inspection reports any to call toString() on a String object. This is entirely redundant. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringToUpperWithoutLocale.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringToUpperWithoutLocale.html index 430b7ae0e578..f6e49b749b56 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StringToUpperWithoutLocale.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringToUpperWithoutLocale.html @@ -4,6 +4,7 @@ This inspection reports any call of toUpperCase() or toLowerCase() on String objects which do not specify a java.util.Locale. Such calls are usually incorrect in an internationalized environment. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/StringTokenizer.html b/plugins/InspectionGadgets/src/inspectionDescriptions/StringTokenizer.html index 29a99c71314f..c13f00b065fe 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/StringTokenizer.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/StringTokenizer.html @@ -2,6 +2,7 @@ This inspection reports any use of the StringTokenizer class. Many uses of StringTokenizer are incorrect in an internationalized environment. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SubstringZero.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SubstringZero.html index 8a88817a6c0f..8605b71b6225 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SubstringZero.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SubstringZero.html @@ -2,6 +2,7 @@ This inspection reports any call to String.substring() with a constant argument equal to zero. Such calls are completely redundant, and may be removed. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SubtractionInCompareTo.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SubtractionInCompareTo.html index edd67d0113e9..b85697114254 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SubtractionInCompareTo.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SubtractionInCompareTo.html @@ -6,6 +6,7 @@ use the results of integer subtraction as the return of a compareTo() method, this construct may cause subtle and difficult bugs in cases of integer overflow. Comparing the integer values directly and returning -1, 0, or 1 is better practice in almost all cases. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SuppressionAnnotation.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SuppressionAnnotation.html index f011ef1dbfd7..2dcb4afad0be 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SuppressionAnnotation.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SuppressionAnnotation.html @@ -1,6 +1,7 @@ This inspection reports any inspection suppression comments or annotations. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SuspiciousIndentAfterControlStatement.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SuspiciousIndentAfterControlStatement.html index 46cdee891024..4d79d5169822 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SuspiciousIndentAfterControlStatement.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SuspiciousIndentAfterControlStatement.html @@ -3,6 +3,7 @@ This inspection reports any suspicious indentation of statements after a control statement without braces. Such indentation can make it look like the statement is part of the control statement, when in fact it will be executed after the control statement. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SuspiciousSystemArraycopy.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SuspiciousSystemArraycopy.html index 8b62d59028a9..1f5515bc5c1c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SuspiciousSystemArraycopy.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SuspiciousSystemArraycopy.html @@ -7,6 +7,7 @@ Warnings reported by this inspection are:

  • source and destination have a different type.
  • source offset, destination offset or length are negative. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SuspiciousToArrayCall.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SuspiciousToArrayCall.html index d4a2edd07c09..585681be15fe 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SuspiciousToArrayCall.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SuspiciousToArrayCall.html @@ -4,6 +4,7 @@ This inspection reports suspicious calls to Collection.toArray(). Reported are calls where the type of the specified array argument is not of the same type as the array type to which the result is casted or the type of the specified array argument does not match the type parameter of the collection declaration. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatement.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatement.html index 34c01082a6d0..3e27942e55da 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatement.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatement.html @@ -2,6 +2,7 @@ This inspection reports switch statements. switch statements are often (but not always) indicators of poor object-oriented design. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatementDensity.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatementDensity.html index 4f71e554d9a0..277d88b5872a 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatementDensity.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatementDensity.html @@ -3,6 +3,7 @@ This inspection reports switch statements with too low a ratio of switch labels to executable statements. Such switch statements may be confusing, and should probably be refactored. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatementWithConfusingDeclaration.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatementWithConfusingDeclaration.html index f569a5914527..7abe1f58622a 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatementWithConfusingDeclaration.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatementWithConfusingDeclaration.html @@ -2,6 +2,7 @@ This inspection reports local variables declared in one branch of a switch statement and used in a different branch. Such declarations can be extremely confusing. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatementWithTooFewBranches.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatementWithTooFewBranches.html index 7fb70fe7782e..9cc83ebd5cd9 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatementWithTooFewBranches.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatementWithTooFewBranches.html @@ -2,6 +2,7 @@ This inspection reports switch statements with too few case labels. Such statements may be more clearly expressed as if statements. +

    Use the field provided below to specify the minimum number of case labels expected.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatementWithTooManyBranches.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatementWithTooManyBranches.html index 5c4112942ba7..c14d989099ab 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatementWithTooManyBranches.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatementWithTooManyBranches.html @@ -1,6 +1,7 @@ This inspection reports switch statements with too many case labels. +

    Use the field provided below to specify the maximum number of case labels expected.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatementsWithoutDefault.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatementsWithoutDefault.html index 4f7ee8033a59..b72457267a5e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatementsWithoutDefault.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SwitchStatementsWithoutDefault.html @@ -2,6 +2,7 @@ This inspection reports switch statements that do not contain default labels. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizationOnLocalVariableOrMethodParameter.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizationOnLocalVariableOrMethodParameter.html index 6fdab03ebac1..ce5d0917e6f4 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizationOnLocalVariableOrMethodParameter.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizationOnLocalVariableOrMethodParameter.html @@ -4,6 +4,7 @@ This inspection reports synchronization on a local variable or parameter. Such synchronization has little effect, since different threads usually will have different values for the local variable or parameter. The intent of the code will usually be clearer if synchronization on a field is used. +

    New in 8, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizationOnStaticField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizationOnStaticField.html index 2528144c95c6..e900fb788244 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizationOnStaticField.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizationOnStaticField.html @@ -2,6 +2,7 @@ This inspection reports synchronization on static fields. While not strictly incorrect, synchronization on static fields can lead to bad performance because of contention. +

    New in 10, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizeOnLock.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizeOnLock.html index 4dc7d1055299..38460cea82f7 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizeOnLock.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizeOnLock.html @@ -4,6 +4,7 @@ This inspection reports any synchronized block which locks on an instance of java.util.concurrent.locks.Lock. Such synchronization is almost certainly inadvertent, and appropriate versions of .lock() and .unlock() should be used instead. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizeOnNonFinalField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizeOnNonFinalField.html index f3841b350d7e..14b803f42b11 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizeOnNonFinalField.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizeOnNonFinalField.html @@ -3,6 +3,7 @@ This inspection reports synchronized statements where the lock expression is a reference to a non-final field. Such statements are unlikely to have useful semantics, as different threads may be locking on different objects even when operating on the same object. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizeOnThis.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizeOnThis.html index 6926ab3459a5..045752aa4d61 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizeOnThis.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizeOnThis.html @@ -7,6 +7,7 @@ blocks which lock this, and calls to wait(), Such constructs, like synchronized methods, make it hard to track just who is locking on a given object, and make possible "denial of service" attacks on objects. As an alternative, consider locking on a private instance variable, access to which can be completely controlled. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizedMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizedMethod.html index 9bb2c0aecc52..bd3f1b107813 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizedMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizedMethod.html @@ -2,6 +2,7 @@ This inspection reports any use of the synchronized modifier on methods. Some coding standards prohibit the use of the synchronized modifier, in favor of synchronized statements. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizedOnLiteralObject.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizedOnLiteralObject.html index 5bca75b85c63..36c0ea7aaf3f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizedOnLiteralObject.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SynchronizedOnLiteralObject.html @@ -7,6 +7,7 @@ Because of this, it is possible that some other part of the system which uses an object initialized with the same literal, is actually holding a reference to the exact same object. This can create unexpected dead-lock situations, if the lock object was thought to be private. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SystemExit.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SystemExit.html index 3eda6122f4e8..cf699cbf431c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SystemExit.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SystemExit.html @@ -3,6 +3,7 @@ This inspection reports the calls to System.exit(), Runtime.exit(), or Runtime.halt(). Calls to these methods make the calling code unportable to most application servers. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SystemGC.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SystemGC.html index faf7e7660e8f..02e14addcc01 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SystemGC.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SystemGC.html @@ -3,6 +3,7 @@ This inspection reports any call of System.gc() or Runtime.gc(). While occasionally useful in testing, explicitly triggering garbage collection via System.gc() is almost always a bad idea in production code, and can result in serious performance problems. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SystemGetenv.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SystemGetenv.html index b7c20f347ce0..b04007533c7b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SystemGetenv.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SystemGetenv.html @@ -2,6 +2,7 @@ This inspection reports the calls to System.getenv(). Calls to System.getenv() are inherently unportable. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SystemOutErr.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SystemOutErr.html index 444d359bb8a5..706854f9c1ab 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SystemOutErr.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SystemOutErr.html @@ -3,6 +3,7 @@ This inspection reports any uses of System.out or System.err. These are often temporary debugging statements, and should probably be either removed from production code, or replaced by a more robust logging facility. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SystemProperties.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SystemProperties.html index e387da2e6ca7..6e2e02a39176 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SystemProperties.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SystemProperties.html @@ -3,6 +3,7 @@ This inspection reports any accesses of the System properties. While accessing the System properties is not a security risk in it self, it is often found in malicious code. Accesses to System properties should be closely examined in any security audit. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SystemRunFinalizersOnExit.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SystemRunFinalizersOnExit.html index 05f30a6f6918..97c8ec68144c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SystemRunFinalizersOnExit.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SystemRunFinalizersOnExit.html @@ -4,6 +4,7 @@ This inspection reports any calls to System.runFinalizersOnExit(). This call is one of the most dangerous in the Java language. It is inherently non-thread-safe, may result in data corruption, deadlock, and may effect parts of the program far removed from its call point. It is deprecated, and its use strongly discouraged. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/SystemSetSecurityManager.html b/plugins/InspectionGadgets/src/inspectionDescriptions/SystemSetSecurityManager.html index a84352d3aa4c..d4a0c26ab913 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/SystemSetSecurityManager.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/SystemSetSecurityManager.html @@ -2,6 +2,7 @@ This inspection reports any calls to System.setSecurityManager(). While often benign, any call to System.setSecurityManager() should be closely examined in any security audit. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TailRecursion.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TailRecursion.html index 23e42bef6a48..4a737f1b88bc 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TailRecursion.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TailRecursion.html @@ -4,6 +4,7 @@ This inspection reports tail recursion, that is when a method calls itself as its last action before returning. Tail recursion can always be replaced by looping, which will be considerably faster. Some JVMs perform this optimization, while others do not. Thus, tail recursive solutions may have considerably different performance characteristics on different virtual machines. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TeardownCallsSuperTeardown.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TeardownCallsSuperTeardown.html index cf3f8b6056ec..d5f48f3936ce 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TeardownCallsSuperTeardown.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TeardownCallsSuperTeardown.html @@ -2,6 +2,7 @@ This inspection reports JUnit classes whose tearDown() method does not call super.tearDown(). +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TeardownIsPublicVoidNoArg.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TeardownIsPublicVoidNoArg.html index 94d20775c287..0f1cfd47076c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TeardownIsPublicVoidNoArg.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TeardownIsPublicVoidNoArg.html @@ -5,6 +5,7 @@ is not declared public, does not return void, or takes arguments. Such tearDown() methods are easy to create inadvertently, and will not be executed by JUnit tests runners. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TestCaseInProductCode.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TestCaseInProductCode.html index c5b611dfd3d9..063aef3522d1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TestCaseInProductCode.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TestCaseInProductCode.html @@ -3,6 +3,7 @@ This inspection reports JUnit test cases in product source trees. This most likely indicates programmer error, and can result in test code being shipped into production. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TestCaseWithConstructor.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TestCaseWithConstructor.html index 2fc9edf50873..10d0de30eb35 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TestCaseWithConstructor.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TestCaseWithConstructor.html @@ -2,6 +2,7 @@ This inspection reports on JUnit test cases with initialization logic in their constructors. Initialization of JUnit test cases should be done in setUp() methods instead. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TestCaseWithNoTestMethods.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TestCaseWithNoTestMethods.html index 9d0f4f3cd1a9..ce6f0b32f7f2 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TestCaseWithNoTestMethods.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TestCaseWithNoTestMethods.html @@ -2,6 +2,7 @@ This inspection reports non-abstract JUnit test cases which do not contain any test methods. Such test cases usually indicate developer error. +

    Use the checkbox below to specify that test cases which have super classes with test methods should be ignored by this inspection. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TestMethodInProductCode.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TestMethodInProductCode.html index b38f0a72fa52..99d6349b085d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TestMethodInProductCode.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TestMethodInProductCode.html @@ -3,6 +3,7 @@ This inspection reports JUnit 4.0 @Test methods in product source trees. This most likely indicates programmer error, and can result in test code being shipped into production. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TestMethodIsPublicVoidNoArg.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TestMethodIsPublicVoidNoArg.html index 56a900f14114..08e9c44761ae 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TestMethodIsPublicVoidNoArg.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TestMethodIsPublicVoidNoArg.html @@ -5,6 +5,7 @@ This inspection reports any JUnit test methods whose names which are not declare void, or take arguments. Such test methods are easy to create inadvertently, but will not be executed by JUnit test runners. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TestMethodWithoutAssertion.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TestMethodWithoutAssertion.html index e818584c3706..34f56927ee49 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TestMethodWithoutAssertion.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TestMethodWithoutAssertion.html @@ -4,6 +4,7 @@ This inspection reports any test methods of JUnit test case classes which do not any assertions. Such methods indicate either incomplete or weak test cases. The table below can be used to specify which class name, method name regular expression combinations qualify as assertions. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TextLabelInSwitchStatement.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TextLabelInSwitchStatement.html index e2c2a0bc8f35..b24219f71504 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TextLabelInSwitchStatement.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TextLabelInSwitchStatement.html @@ -11,6 +11,7 @@ While occasionally intended, this construction is often the result of a typo. break; } +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ThisEscapedInConstructor.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ThisEscapedInConstructor.html index d9beb96f1edf..3ed3ec28e496 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ThisEscapedInConstructor.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ThisEscapedInConstructor.html @@ -5,6 +5,7 @@ during object construction. Escapes occur when this is used as a method argument or the object of an assignment in a constructor or initializer. Such escapes may result in subtle bugs, as the object is now available in a context in which it is not guaranteed to be initialized. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadDeathRethrown.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadDeathRethrown.html index 7f0e1716f6b5..6c86eaccf6f1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadDeathRethrown.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadDeathRethrown.html @@ -2,6 +2,7 @@ This inspection reports try statements which catch java.lang.ThreadDeath which do not rethrow the exception. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadDumpStack.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadDumpStack.html index 84ed7e7766ae..991ea1e90333 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadDumpStack.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadDumpStack.html @@ -3,6 +3,7 @@ This inspection reports any uses Thread.dumpStack(). These are often temporary debugging statements, and should probably be either removed from production code, or replaced by a more robust logging facility. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadLocalNotStaticFinal.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadLocalNotStaticFinal.html index 897b49000675..c99538daad50 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadLocalNotStaticFinal.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadLocalNotStaticFinal.html @@ -5,6 +5,7 @@ associates state with a thread. A non-static non-final java.lang.ThreadLocal field associates state with an instance-thread combination. This is seldom necessary and often a bug which can cause memory leaks and possibly incorrect behavior. +

    This inspection has a quick fix to make the field static final

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadPriority.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadPriority.html index 3024761e0017..28f7897722f7 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadPriority.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadPriority.html @@ -4,6 +4,7 @@ This inspection reports any calls to Thread.setPriority(). Modifying priorities of threads is an inherently non-portable operation, as no guarantees are given in the Java specification of how priorities are used in scheduling threads, or even if they are used at all. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadRun.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadRun.html index 113d710c92d3..f32f56e74569 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadRun.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadRun.html @@ -2,6 +2,7 @@ This inspection reports any calls to run() on java.lang.Thread or any of its subclasses. While occasionally intended, this is usually a mistake, with start() intended instead. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadStartInConstruction.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadStartInConstruction.html index b4cf4756159a..5945b01b8ad9 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadStartInConstruction.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadStartInConstruction.html @@ -4,6 +4,7 @@ This inspection reports any calls to start() on java.lang.Thread or any of its subclasses during object construction. While occasionally useful, this construct should be avoided due to inheritance issues. Subclasses of a class which launches a thread during object construction will not have finished any initialization logic of their own before the thread has launched. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadStopSuspendResume.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadStopSuspendResume.html index 793e9d6f039f..573ab22b46f3 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadStopSuspendResume.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadStopSuspendResume.html @@ -4,6 +4,7 @@ This inspection reports any calls to Thread.stop(), Thread.suspend(), or Thread.resume(). These calls are inherently prone to data corruption and deadlock, and their use is strongly discouraged. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadWithDefaultRunMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadWithDefaultRunMethod.html index b12f3725f4a4..038bd8e98e69 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadWithDefaultRunMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadWithDefaultRunMethod.html @@ -3,6 +3,7 @@ This inspection reports Thread instances being created without specifying a Runnable parameter or overriding the run() method. Such threads do nothing useful. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadYield.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadYield.html index df4e41dea5c9..a949f32ff4da 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadYield.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreadYield.html @@ -3,6 +3,7 @@ This inspection reports any calls to Thread.yield(). Thread.yield() has no useful guaranteed semantics, and is often used by inexperienced programmers to mask race conditions. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreeNegationsPerMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreeNegationsPerMethod.html index 90ddf6265e62..9a3e7ee280bd 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ThreeNegationsPerMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ThreeNegationsPerMethod.html @@ -2,6 +2,7 @@ This inspection reports methods with three or more negation operations (! or !=). Such methods may be unnecessarily confusing. +

    Use the checkbox below to disable this inspection within 'equals()' methods.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowCaughtLocally.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowCaughtLocally.html index f5b8272dbe2b..b3ef4bed1d4b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowCaughtLocally.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowCaughtLocally.html @@ -3,6 +3,7 @@ This inspection reports throw statements whose exceptions are always caught by containing try statements. Using throw statements as a "goto" to change the local flow of control is both confusing and likely to have poor performance. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowFromFinallyBlock.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowFromFinallyBlock.html index 0035c4f4181b..85692daf4b99 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowFromFinallyBlock.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowFromFinallyBlock.html @@ -3,6 +3,7 @@ This inspection reports throw statements inside of finally blocks. While occasionally intended, such throw statements may mask exceptions thrown, and tremendously complicate debugging. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowableInstanceNeverThrown.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowableInstanceNeverThrown.html index 3a879fc29b7a..b9aa1e7901af 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowableInstanceNeverThrown.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowableInstanceNeverThrown.html @@ -3,6 +3,7 @@ This inspection reports Throwable instantiation, where the created Throwable is never actually thrown. Most often this is the result of a simple mistake. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowablePrintStackTrace.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowablePrintStackTrace.html index 63a697fb4888..a9ab15769727 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowablePrintStackTrace.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowablePrintStackTrace.html @@ -3,6 +3,7 @@ This inspection reports any uses Throwable.printStackTrace() without arguments. These are often temporary debugging statements, and should probably be either removed from production code, or replaced by a more robust logging facility. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowableResultOfMethodCallIgnored.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowableResultOfMethodCallIgnored.html index fd9f7e733bc3..c5a44ce50f07 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowableResultOfMethodCallIgnored.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowableResultOfMethodCallIgnored.html @@ -4,6 +4,7 @@ This inspection reports calls to specific methods where the result of the call is ignored and which return an object of type (or subtype of) Throwable. Usually these types of methods are meant as factory methods for exceptions and the result should be thrown. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ThrownExceptionsPerMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ThrownExceptionsPerMethod.html index f00a4298bba5..6cb190314d65 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ThrownExceptionsPerMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ThrownExceptionsPerMethod.html @@ -3,6 +3,7 @@ This inspection reports methods that are declared as throwing too many different types of exceptions. Methods with too many exceptions declared are a good sign that your error handling code is getting overly complex. +

    Use the field provided below to specify the maximum acceptable number of throw clauses a method might have.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowsRuntimeException.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowsRuntimeException.html index b15f6435c02f..9bb58d7d9e41 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowsRuntimeException.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ThrowsRuntimeException.html @@ -2,6 +2,7 @@ This inspection reports declarations of unchecked exceptions (RuntimeException and its subclasses) in the throws clause of a method. Declaration of unchecked exceptions are not required and may be removed. +

    New in 11, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TimeToString.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TimeToString.html index f9ec73c13bc0..da7ada1317de 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TimeToString.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TimeToString.html @@ -2,6 +2,7 @@ This inspection reports any call of toString() on java.sql.Time objects. Such calls are usually incorrect in an internationalized environment. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ToArrayCallWithZeroLengthArrayArgument.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ToArrayCallWithZeroLengthArrayArgument.html index 1c22f7e9c842..2bc010028e50 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ToArrayCallWithZeroLengthArrayArgument.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ToArrayCallWithZeroLengthArrayArgument.html @@ -6,6 +6,7 @@ with a zero-length array argument. When passing in an array of too small size, t toArray() method has to construct a new array of the right size using reflection. This has significantly worse performance than passing in an array of at least the size of the collection itself. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TodoComment.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TodoComment.html index a734e65dbaaa..0bd6e18b4dae 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TodoComment.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TodoComment.html @@ -4,6 +4,7 @@ This inspection reports "TODO" comments in your code. Format of "TODO" comments is configurable via the Settings | TODO panel. Since IDEA already provides syntax highlighting for "TODO" comments, it is expected that this will largely be used in batch mode. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TooBroadCatch.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TooBroadCatch.html index 8b5e20ed78ea..3886d90dcb5d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TooBroadCatch.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TooBroadCatch.html @@ -2,6 +2,7 @@ This inspection reports catch blocks which have parameters which are more generic than the exceptions thrown by the corresponding try block. +

    Use the first checkbox below to have this inspection only warn on the most generic exceptions.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TooBroadScope.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TooBroadScope.html index 61fcab875232..afba3f269bc2 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TooBroadScope.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TooBroadScope.html @@ -3,6 +3,7 @@ This inspection reports any variable declarations of which the scope can be narrowed. Especially useful for "Pascal style" declarations at the start of a method, but variables with too broad a scope are also often left over after refactorings. +

    Use the checkbox below to enable this inspection to report variables which are initialized with a call to a constructor. This makes the inspection potentially unsafe in cases where the diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TransientFieldInNonSerializableClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TransientFieldInNonSerializableClass.html index 148683a7c9c6..3da13577232e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TransientFieldInNonSerializableClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TransientFieldInNonSerializableClass.html @@ -1,6 +1,7 @@ This inspection reports transient fields in non-Serializable classes. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TransientFieldNotInitialized.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TransientFieldNotInitialized.html index 2d0af00f0450..4f11ed9057b0 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TransientFieldNotInitialized.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TransientFieldNotInitialized.html @@ -8,6 +8,7 @@ to be initialized separately in a readObject method during deserialization. Any transient fields which are not initialized during normal object construction are considered to use the default initialization and are not reported by this inspection. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TrivialIf.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TrivialIf.html index 07d0e1fc40d5..28a8dcb2f88e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TrivialIf.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TrivialIf.html @@ -15,6 +15,7 @@ can be simplified to

         return foo();
     
    +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TrivialStringConcatenation.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TrivialStringConcatenation.html index e7d340137a71..cafc4c79ead8 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TrivialStringConcatenation.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TrivialStringConcatenation.html @@ -3,6 +3,7 @@ This inspection reports string concatenations where one of the arguments is the empty string. Such a concatenation is unnecessary and inefficient, particularly when used as an idiom for formatting non-String objects or primitives into Strings. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TryFinallyCanBeTryWithResources.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TryFinallyCanBeTryWithResources.html index 0cea3957fe4c..09a61fc3e264 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TryFinallyCanBeTryWithResources.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TryFinallyCanBeTryWithResources.html @@ -6,6 +6,7 @@ statement into a try with resources statement.

    This inspection only reports if the project or module is configured to use a language level of 7.0 or higher. +

    New in 10.5, Powered by InspectionGadgets \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TryWithIdenticalCatches.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TryWithIdenticalCatches.html index a72356b31c78..1af3727458ed 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TryWithIdenticalCatches.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TryWithIdenticalCatches.html @@ -5,6 +5,7 @@ a multi-catch section.

    This inspection only reports if the project or module is configured to use a language level of 7.0 or higher. +

    New in 10.5, Powered by InspectionGadgets \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TypeMayBeWeakened.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TypeMayBeWeakened.html index ba0cae8c8001..b1432d192d54 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TypeMayBeWeakened.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TypeMayBeWeakened.html @@ -4,6 +4,7 @@ This inspection reports any variables which may be declared with a weaker type. a variable may be of type ArrayList, and only the method isEmpty() is called on it. In this case the type List would do just as well. +

    Enable the first checkbox below to prevent weakening the left side of assignments when the right side is not a type cast or new expression. When storing the result of a method call in a variable, it is diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TypeParameterExtendsFinalClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TypeParameterExtendsFinalClass.html index b18d17e10319..33ce8fc8f4f0 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TypeParameterExtendsFinalClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TypeParameterExtendsFinalClass.html @@ -3,6 +3,7 @@ This inspection reports any type parameters declared to extend a final class. Since final classes cannot be extended, the type parameter could be replaced with the type of the specified final class. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TypeParameterExtendsObject.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TypeParameterExtendsObject.html index d5774c1d3b71..331cc6e30a78 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TypeParameterExtendsObject.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TypeParameterExtendsObject.html @@ -1,6 +1,7 @@ This inspection reports any type parameters explicitly declared to extend java.lang.Object. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TypeParameterHidesVisibleType.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TypeParameterHidesVisibleType.html index 9254559a8f38..eee84bde3165 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TypeParameterHidesVisibleType.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TypeParameterHidesVisibleType.html @@ -2,6 +2,7 @@ This inspection reports type parameters being named identically to visible types in the current scope. Such a parameter name may be confusing. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TypeParameterNamingConvention.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TypeParameterNamingConvention.html index d2d5a416ec7b..b62686856a63 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/TypeParameterNamingConvention.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TypeParameterNamingConvention.html @@ -2,6 +2,7 @@ This inspection reports type parameters whose names are either too short, too long, or do not follow the specified regular expression pattern. +

    Use the fields provided below to specify minimum length, maximum length and regular expression expected for type parameter names. (Regular expressions are in standard java.util.regex format.) diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnaryPlus.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnaryPlus.html index abf0c54ced4b..ab80c36d2d45 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnaryPlus.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnaryPlus.html @@ -2,6 +2,7 @@ This inspection reports any uses of the unary '+' operator. Unary plus is a null operation, and its presence may represent a coding error, particularly in combination with the increment operator, '++'. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UncheckedExceptionClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UncheckedExceptionClass.html index 84b2e4bbbf18..948575118ee7 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UncheckedExceptionClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UncheckedExceptionClass.html @@ -2,6 +2,7 @@ This inspection reports unchecked exception classes (i.e. subclasses of RuntimeException). Certain coding standards require that all user-defined exception classes be checked. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnclearBinaryExpression.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnclearBinaryExpression.html index 8d225a594857..0ae379004d08 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnclearBinaryExpression.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnclearBinaryExpression.html @@ -3,6 +3,7 @@ This inspection reports binary expressions consisting of multiple terms with different operators without parentheses. Such expressions can be unclear because not every developer is intimately familiar with all the precedence rules of the different operators. This inspection has a quickfix which adds clarifying parentheses. +

    New in 11, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnconditionalWait.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnconditionalWait.html index a180b72e0242..f6256660a488 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnconditionalWait.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnconditionalWait.html @@ -8,6 +8,7 @@ is called unconditionally, that often indicates that the condition was checked b acquired. In that case a data race may occur, with the condition becoming true between the time it was checked and the time the lock was acquired. While constructs found by this inspection are not necessarily incorrect, they are certainly worth examining. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnconstructableTestCase.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnconstructableTestCase.html index d0b4974d8be6..1b03e626285c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnconstructableTestCase.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnconstructableTestCase.html @@ -4,6 +4,7 @@ This inspection reports non-abstract JUnit test cases which do not expose a public no-arg constructor or a public constructor which takes a single string as an argument. Such test cases will be unrunnable by most JUnit test runners, including IDEA's. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarilyQualifiedInnerClassAccess.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarilyQualifiedInnerClassAccess.html index d29db28c7692..cb3fc83052b3 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarilyQualifiedInnerClassAccess.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarilyQualifiedInnerClassAccess.html @@ -3,6 +3,7 @@ This inspection reports any references to inner classes which are unnecessarily qualified with the name of the enclosing class. Such qualification is unnecessary, and may be safely removed. This may require the addition of an import for the inner class. +

    Use the checkbox below to ignore references to inner classes where the removal of the qualification would require the addition of an import. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarilyQualifiedStaticUsage.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarilyQualifiedStaticUsage.html index 9e17979398a5..d98a34bd3f78 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarilyQualifiedStaticUsage.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarilyQualifiedStaticUsage.html @@ -3,6 +3,7 @@ This inspection reports calls to static methods or accesses of static fields on the current class which are qualified with the class name. Such qualification is unnecessary, and may be safely removed. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarilyQualifiedStaticallyImportedElement.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarilyQualifiedStaticallyImportedElement.html index 0330d96f622f..0dc768bc3878 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarilyQualifiedStaticallyImportedElement.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarilyQualifiedStaticallyImportedElement.html @@ -3,6 +3,7 @@ This inspection reports any references to static members which are statically imported and also qualified with their containing class name. Because the elements are already statically imported such qualification is unnecessary and can be removed. +

    New in 10, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryBlockStatement.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryBlockStatement.html index f4f29be79764..1eb2f2f6e582 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryBlockStatement.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryBlockStatement.html @@ -4,6 +4,7 @@ This inspection reports code blocks which are unnecessary to the semantics of th be replaced by their contents. Code blocks which are the bodies of if, do, while or for statements will not be reported by this inspection. +

    Use the checkbox below if you wish this inspection to ignore code blocks which are used as branches of switch statements.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryBoxing.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryBoxing.html index 7dc8ecb98c85..bbfa5f157d48 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryBoxing.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryBoxing.html @@ -5,6 +5,7 @@ Boxing is unnecessary under Java 5 and newer, and can be safely removed.

    This inspection only reports if the project or module is configured to use a language level of 5.0 or higher. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryCallToStringValueOf.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryCallToStringValueOf.html index 8da882fb6eab..c31d5c548b0d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryCallToStringValueOf.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryCallToStringValueOf.html @@ -3,6 +3,7 @@ This inspection reports on any calls to String.valueOf() used in string concatenations. The conversion to string is handled automatically by the compiler without a call to String.valueOf(), making it unnecessary. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryConditionalExpression.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryConditionalExpression.html index c5b594593c49..b2dfaca4f705 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryConditionalExpression.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryConditionalExpression.html @@ -3,6 +3,7 @@ This inspection reports conditional expressions of the form condition?true:false or condition?false:true. These expressions may be safely simplified to condition or !condition, respectively. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryConstantArrayCreationExpression.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryConstantArrayCreationExpression.html index 7074bddef73b..0cd642ec5a6c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryConstantArrayCreationExpression.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryConstantArrayCreationExpression.html @@ -4,6 +4,7 @@ This inspection reports any constant new array expression which can be replaced with an array initializer. Array initializers omit the type declaration because that is already specified by the declaration of the variable the expression is assigned to. +

    New in 8, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryConstructor.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryConstructor.html index 362650071dd1..f0730702a750 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryConstructor.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryConstructor.html @@ -4,6 +4,7 @@ This inspection reports unnecessary empty constructors without parameters with t access modifiers as their containing class. If such a constructor is the only constructor for a class and performs no initialization, it can be safely removed. +

    Use the checkbox below to ignore unnecessary constructors which have an annotation.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryContinue.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryContinue.html index 0ff662a669fa..7390e671e90a 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryContinue.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryContinue.html @@ -4,6 +4,7 @@ This inspection reports on any unnecessary continue statements at the end These may be safely removed.

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

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryDefault.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryDefault.html index d62442e63669..8729e528d1da 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryDefault.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryDefault.html @@ -4,6 +4,7 @@ This inspection reports switch statements with default branches which can never be taken. At present, such branches are only marked for switch statements over enumerated types all of whose values have corresponding case branches. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryEnumModifier.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryEnumModifier.html index b9121d12bd43..dd5d87692452 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryEnumModifier.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryEnumModifier.html @@ -2,6 +2,7 @@ This inspection reports on any redundant modifiers on enumerated classes or components of enumerated classes. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryExplicitNumericCast.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryExplicitNumericCast.html index 0330989c2cff..3a982e7833e8 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryExplicitNumericCast.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryExplicitNumericCast.html @@ -2,6 +2,7 @@ This inspection reports any primitive numeric casts which would otherwise be inserted implicitly by the compiler. +

    New in 11, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryFinalOnLocalVariableOrParameter.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryFinalOnLocalVariableOrParameter.html index facd1c1d8821..63ede42070cc 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryFinalOnLocalVariableOrParameter.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryFinalOnLocalVariableOrParameter.html @@ -2,6 +2,7 @@ This inspection reports local variables or parameters unnecessarily declared final. Some coding standards frown on variables declared final, for reasons of terseness. +

    Use the first checkbox below to enable or disable warnings on local variables

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryFullyQualifiedName.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryFullyQualifiedName.html index ee351edc260d..74325ad91611 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryFullyQualifiedName.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryFullyQualifiedName.html @@ -2,6 +2,7 @@ This inspection reports on fully qualified class names which can be shortened. The quick fix for this inspection will shorten the fully qualified names, adding import statements as necessary. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryInheritDoc.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryInheritDoc.html index 8b3ae0b1bc88..6e0cf9a29e2d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryInheritDoc.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryInheritDoc.html @@ -5,6 +5,7 @@ This inspection reports any Javadoc comments which contain only the tag. Since Javadoc copies the super class' comment if no comment is present, a comment containing only an {@inheritDoc} adds nothing. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryInterfaceModifier.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryInterfaceModifier.html index cf591ca801eb..3e9597c94b79 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryInterfaceModifier.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryInterfaceModifier.html @@ -1,6 +1,7 @@ This inspection reports any redundant modifiers on interfaces or interface components. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryJavaDocLink.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryJavaDocLink.html index ea025d236e26..300766b02523 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryJavaDocLink.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryJavaDocLink.html @@ -6,6 +6,7 @@ tags which reference the method owning the comment, the super method of the method owning the comment or the class containing the comment. Such links are unnecessary and can be safely removed using this inspections quickfix. The quickfix will remove the entire Javadoc comment if the link is its only content. +

    Use the checkbox below to ignore inline links ({@link} and {@linkplain}) to super methods. While a link to all super methods is automatically added by the diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryLabelOnBreakStatement.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryLabelOnBreakStatement.html index 9d6781904f8c..4efb7471702e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryLabelOnBreakStatement.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryLabelOnBreakStatement.html @@ -2,6 +2,7 @@ This inspection reports break statements with unnecessary labels. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryLabelOnContinueStatement.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryLabelOnContinueStatement.html index dbea21cffa93..873ba23dc40a 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryLabelOnContinueStatement.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryLabelOnContinueStatement.html @@ -2,6 +2,7 @@ This inspection reports continue statements with unnecessary labels. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryLocalVariable.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryLocalVariable.html index a6fbb6d84c34..cfa7deb84430 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryLocalVariable.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryLocalVariable.html @@ -5,6 +5,7 @@ nothing to the comprehensibility of a method. Variables caught include local var which are immediately returned, local variables that are immediately assigned to another variable and then not used, and local variables which always have the same value as another local variable or parameter. +

    Use the checkbox below to have this inspection ignore variables which are immediately returned or thrown. Some coding styles suggest using such variables for clarity and diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryParentheses.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryParentheses.html index 81aebf79f491..aa4d3ad96e2d 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryParentheses.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryParentheses.html @@ -3,11 +3,13 @@ This inspection reports on any instance of unnecessary parentheses. Parentheses are considered unnecessary if the evaluation order of an expression remains unchanged if the parentheses are removed. +

    Use the first checkbox below to ignore parentheses which help to clarify a binary expression. Parentheses are clarifying if the expression parenthesized is an instanceof expression part of a larger -expression or has a different operator than the parent expression.
    +expression or has a different operator than the parent expression. +

    Use the second checkbox below to ignore any parentheses around the condition of conditional expressions. Some coding standards specify that all such conditions must be surrounded by parentheses. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryQualifierForThis.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryQualifierForThis.html index 8b9874857c6e..e982a4d3f833 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryQualifierForThis.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryQualifierForThis.html @@ -6,6 +6,7 @@ disambiguate a code reference may easily become unnecessary via automatic refact

    Sample: OuterClass.this.foo(); +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryReturn.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryReturn.html index 6d810b1f1210..152899df400a 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryReturn.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryReturn.html @@ -4,6 +4,7 @@ This inspection reports on any unnecessary return statements at the end o void. These may be safely removed.

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

    Use the checkbox below to let this inspection ignore return statements in the then branch of if statements which also have an else branch. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarySemicolon.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarySemicolon.html index 9454c0a20573..879e9b96624e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarySemicolon.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarySemicolon.html @@ -2,6 +2,7 @@ This inspection reports on any unnecessary semicolons, whether between class members, inside block statements, or after class definitions. While valid Java, these semicolons are redundant, and may be removed. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarySuperConstructor.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarySuperConstructor.html index eff25ad94266..9d4e2aab3fab 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarySuperConstructor.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarySuperConstructor.html @@ -1,7 +1,8 @@ This inspection reports any no-argument calls to a superclass -constructor as the first call of a constructor. Such calls are unnecessary, and may be removed. +constructor as the first call of a constructor. Such calls are unnecessary, and may be removed.

    +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarySuperQualifier.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarySuperQualifier.html index c933c52e4ed2..a4cf972ee67c 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarySuperQualifier.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessarySuperQualifier.html @@ -3,6 +3,7 @@ This inspection reports any unnecessary uses of the super qualifier in method calls and fields references. A super qualifier is unnecessary when the field or method of the super class is not overridden in the calling class. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryTemporaryOnConversionFromString.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryTemporaryOnConversionFromString.html index 2313f4ebe1c4..0ab695ddf467 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryTemporaryOnConversionFromString.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryTemporaryOnConversionFromString.html @@ -11,6 +11,7 @@ will be reported, and can be automatically converted to:

         Integer.valueOf("3")
     
    +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryTemporaryOnConversionToString.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryTemporaryOnConversionToString.html index b9d8ce6e4d85..af2b1331a8fc 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryTemporaryOnConversionToString.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryTemporaryOnConversionToString.html @@ -11,6 +11,7 @@ will be reported, and can be automatically converted to:

         Integer.toString(3)
     
    +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryThis.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryThis.html index 4121eefa9971..edba3d48f9ff 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryThis.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryThis.html @@ -7,6 +7,7 @@ by many coding styles.

    Sample: this.a=3; +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryUnaryMinus.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryUnaryMinus.html index cecc9c4e5e65..0286d37e5a72 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryUnaryMinus.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryUnaryMinus.html @@ -12,6 +12,7 @@ could be replaced by: i -= 8; i = i - 8; +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryUnboxing.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryUnboxing.html index 787d60a372cf..b98af0a7d398 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryUnboxing.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryUnboxing.html @@ -5,6 +5,7 @@ Unboxing is unnecessary under Java 5 and newer, and can be safely removed.

    This inspection only reports if the project or module is configured to use a language level of 5.0 or higher. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnpredictableBigDecimalConstructorCall.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnpredictableBigDecimalConstructorCall.html index 8f20eb866200..d9f3a966c724 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnpredictableBigDecimalConstructorCall.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnpredictableBigDecimalConstructorCall.html @@ -5,6 +5,7 @@ constructors which accept a double value. These constructors can have somewhat unpredictable results because many numbers cannot be represented exactly in a double. It is recommend to use the constructors which accept a String instead. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnqualifiedFieldAccess.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnqualifiedFieldAccess.html index 626f33679f23..164729e83515 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnqualifiedFieldAccess.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnqualifiedFieldAccess.html @@ -4,6 +4,7 @@ This inspection reports on field accesses which are not qualified with this or some other qualifier. Some coding styles mandate that all field accesses are qualified to prevent confusion with local variable or parameter accesses. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnqualifiedInnerClassAccess.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnqualifiedInnerClassAccess.html index 77f370cfc018..86c99c69e360 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnqualifiedInnerClassAccess.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnqualifiedInnerClassAccess.html @@ -2,6 +2,7 @@ This inspection reports any references to inner classes which are not qualified with the name of the enclosing class. +

    Use the checkbox below to ignore references to local inner classes that do not require an import.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnqualifiedMethodAccess.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnqualifiedMethodAccess.html index ccc56963441a..8b14d83f4705 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnqualifiedMethodAccess.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnqualifiedMethodAccess.html @@ -1,6 +1,7 @@ This inspection reports calls to non-static methods of the same object which are not qualified with this. +

    New in 11, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnqualifiedStaticUsage.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnqualifiedStaticUsage.html index 3ab895719c0f..13e57f63fe03 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnqualifiedStaticUsage.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnqualifiedStaticUsage.html @@ -3,6 +3,7 @@ This inspection reports static method calls or field accesses that are not qualified with the class name of the static method. This is legal if the static method or field is in the same class as the call, but may be confusing. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnsecureRandomNumberGeneration.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnsecureRandomNumberGeneration.html index 3a4de91d5c02..6f8fdf35f552 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnsecureRandomNumberGeneration.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnsecureRandomNumberGeneration.html @@ -4,6 +4,7 @@ This inspection reports any uses of java.lang.Random or java.lang.math.Random(). In secure environments, java.secure.SecureRandom is a better choice, offering cryptographically secure random number generation. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnusedCatchParameter.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnusedCatchParameter.html index 202a563c522e..c3af86c3a805 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnusedCatchParameter.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnusedCatchParameter.html @@ -4,6 +4,7 @@ This inspection reports any catch parameters that are unused in their corresponding blocks. This inspection will not report any catch parameters named "ignore" or "ignored". Conversely this inspection will warn on any catch parameters named "ignore" or "ignored" that are actually used. +

    Use the first checkbox below to disable this inspection for catch blocks with comments.

    diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnusedImport.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnusedImport.html index 006d2d010600..958b156eeffd 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnusedImport.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnusedImport.html @@ -3,6 +3,7 @@ This inspection reports any import statements that are unused. Since IDEA can automatically detect and fix such statements with its "Optimize Imports" command, this inspection is mostly useful for off-line reporting on code bases that you don't intend to change. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnusedLabel.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnusedLabel.html index 2dc847c8e63d..f1a372a491cb 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnusedLabel.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnusedLabel.html @@ -1,6 +1,7 @@ This inspection reports unused code labels. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UpperCaseFieldNameNotConstant.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UpperCaseFieldNameNotConstant.html index 866060f2887e..752424cd4db5 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UpperCaseFieldNameNotConstant.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UpperCaseFieldNameNotConstant.html @@ -3,6 +3,7 @@ This inspection reports non-static non-final fields whose names are all upper-case. Such fields may cause confusion by breaking a common naming convention, and are often the result of developer error. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfAWTPeerClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfAWTPeerClass.html index e9e3ae57e032..591a5278d5fb 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfAWTPeerClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfAWTPeerClass.html @@ -3,6 +3,7 @@ This inspection reports any uses of concrete AWT peer classes. Such classes represent native windowing system widgets, and will be non-portable between different windowing systems. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfAnotherObjectsPrivateField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfAnotherObjectsPrivateField.html index 3139fa12f405..afe8bff54fb4 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfAnotherObjectsPrivateField.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfAnotherObjectsPrivateField.html @@ -6,9 +6,11 @@ some coding styles discourage this use. Additionally, such direct access to priv may fail in component-oriented architectures such (e.g. Spring, Hibernate) which expect all access to other objects to be through method calls so as to allow the framework to mediate all access using proxies. +

    Use the first checkbox below to ignore accesses from the same class and only report accesses -from inner or outer classes.
    +from inner or outer classes. +

    Use the second checkbox below to ignore accesses from an equals() method.

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfJDBCDriverClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfJDBCDriverClass.html index 43b52c42f4f2..cf5787091e96 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfJDBCDriverClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfJDBCDriverClass.html @@ -3,6 +3,7 @@ This inspection reports any uses of concrete JDBC driver classes. Use of such classes will bind your project to a specific database and driver, defeating the purpose of JDBC and resulting in loss of portability. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfObsoleteAssert.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfObsoleteAssert.html index 8f75339f6c37..979c2889adef 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfObsoleteAssert.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfObsoleteAssert.html @@ -2,6 +2,7 @@ This inspection reports any calls to methods from the junit.framework.Assert class. This class is obsolete and the calls can be replaced by calls to methods from the org.junit.Assert class. +

    New in 11, Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfProcessBuilder.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfProcessBuilder.html index 730a515be8da..5edf75680e77 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfProcessBuilder.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfProcessBuilder.html @@ -2,6 +2,7 @@ This inspection reports the uses of java.lang.ProcessBuilder. Uses of ProcessBuilder are inherently unportable between operating systems. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfPropertiesAsHashtable.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfPropertiesAsHashtable.html index ee977c6de390..5fd9848b0a60 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfPropertiesAsHashtable.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfPropertiesAsHashtable.html @@ -6,6 +6,7 @@ methods put(), putAll() or For reasons lost to history, Properties inherits from Hashtable, but use of those methods is discouraged to prevent corruption of properties values with non-String data. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfSunClasses.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfSunClasses.html index 0a04bd4d2c32..68fc023bb80b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfSunClasses.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UseOfSunClasses.html @@ -2,6 +2,7 @@ This inspection reports any uses of classes from the sun.* hierarchy. Such classes are non-portable between different JVM's. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UtilityClassWithPublicConstructor.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UtilityClassWithPublicConstructor.html index 86630edc8ae0..c42215b0e090 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UtilityClassWithPublicConstructor.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UtilityClassWithPublicConstructor.html @@ -3,6 +3,7 @@ This inspection reports utility classes with public constructors. Utility classes have all fields and methods declared static. Giving such classes a public constructor is confusing, and may lead to the class being inadvertently instantiated. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/VarargParameter.html b/plugins/InspectionGadgets/src/inspectionDescriptions/VarargParameter.html index 186f04aecbb3..759c57484b67 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/VarargParameter.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/VarargParameter.html @@ -2,6 +2,7 @@ This inspection reports methods taking variable numbers of parameters. Such methods are not supported under Java 1.4 or earlier JVMs. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/VariableNotUsedInsideIf.html b/plugins/InspectionGadgets/src/inspectionDescriptions/VariableNotUsedInsideIf.html index 70e0009b14b2..4cc8c463dfd3 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/VariableNotUsedInsideIf.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/VariableNotUsedInsideIf.html @@ -2,10 +2,11 @@ This inspection reports any references to variables which are checked for nullity in the condition of an if statement or -conditional, expression but which are not used inside the +conditional expression but which are not used inside the if statement. Usually this either means that the check is unnecessary or that the variable is not referenced inside the if statement because of a typo. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/VolatileArrayField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/VolatileArrayField.html index 0c21226e9b75..338ac01fb4bb 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/VolatileArrayField.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/VolatileArrayField.html @@ -5,6 +5,7 @@ which are declared as volatile. Such fields may be confusing, as accessing the array itself follows the rules for volatile fields, but accessing the array's contents does not. If such volatile access is needed to array contents, the JDK5.0 java.util.concurrent.atomic classes should be used instead. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/VolatileLongOrDoubleField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/VolatileLongOrDoubleField.html index 84ce2b1649cd..ff4464bbd4c2 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/VolatileLongOrDoubleField.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/VolatileLongOrDoubleField.html @@ -4,6 +4,7 @@ This inspection reports fields of type long or double which are declared as volatile. While Java specifies that reads and writes from such fields are atomic, many JVM's have violated this specification. Unless you are certain of your JVM, it is better to synchronized access to such fields rather than declare them volatile. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/WaitCalledOnCondition.html b/plugins/InspectionGadgets/src/inspectionDescriptions/WaitCalledOnCondition.html index a4dd0429d212..901268c41da6 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/WaitCalledOnCondition.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/WaitCalledOnCondition.html @@ -4,6 +4,7 @@ This inspection reports on any call to wait() made on a java.util.concurrent.locks.Condition object. This is probably a programming error, and some variant of the await() method was intended instead. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/WaitNotInLoop.html b/plugins/InspectionGadgets/src/inspectionDescriptions/WaitNotInLoop.html index c8dd2ae9ea72..9f96d1a14b14 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/WaitNotInLoop.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/WaitNotInLoop.html @@ -3,6 +3,7 @@ This inspection reports on any call to wait() not made inside a loop. wait() is normally used to suspend a thread until a condition is true, and that condition should be checked after the wait() returns. A loop is the clearest way to achieve this. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/WaitNotInSynchronizedContext.html b/plugins/InspectionGadgets/src/inspectionDescriptions/WaitNotInSynchronizedContext.html index afa02ecd9933..46ef9780aeb3 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/WaitNotInSynchronizedContext.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/WaitNotInSynchronizedContext.html @@ -5,6 +5,7 @@ statement or synchronized method. Calling wait() on an object without holding a lock on that object will result in an IllegalMonitorStateException being thrown. Such a construct is not necessarily an error, as the necessary lock may be acquired before the containing method is called, but its worth looking at. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/WaitOrAwaitWithoutTimeout.html b/plugins/InspectionGadgets/src/inspectionDescriptions/WaitOrAwaitWithoutTimeout.html index 9f4939a6d0f1..b9427961f436 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/WaitOrAwaitWithoutTimeout.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/WaitOrAwaitWithoutTimeout.html @@ -6,6 +6,7 @@ component may result in blockages of the waiting component, if notify()/notifyAll() or signal()/signalAll() never get called. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/WaitWhileHoldingTwoLocks.html b/plugins/InspectionGadgets/src/inspectionDescriptions/WaitWhileHoldingTwoLocks.html index e53489649d91..8256b064cbc1 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/WaitWhileHoldingTwoLocks.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/WaitWhileHoldingTwoLocks.html @@ -3,6 +3,7 @@ This inspection reports .wait() being called while the current thread is holding two locks. Since the call to .wait() only frees locks on the its target, waiting with two locks held can easily lead to deadlock. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/WaitWithoutCorrespondingNotify.html b/plugins/InspectionGadgets/src/inspectionDescriptions/WaitWithoutCorrespondingNotify.html index ad0d1ee50ac3..def93c7f20af 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/WaitWithoutCorrespondingNotify.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/WaitWithoutCorrespondingNotify.html @@ -4,6 +4,7 @@ This inspection reports on any call to Object.wait() for which no call to a corresponding Object.notify() or Object.notifyAll() can be found. Only calls which target fields of the current class are reported by this inspection. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/WhileCanBeForeach.html b/plugins/InspectionGadgets/src/inspectionDescriptions/WhileCanBeForeach.html index c7dca27fc5f2..f996f5e0a0bd 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/WhileCanBeForeach.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/WhileCanBeForeach.html @@ -6,6 +6,7 @@ which is available in Java 5 and newer.

    This inspection only reports if the project or module is configured to use a language level of 5.0 or higher. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/WhileLoopSpinsOnField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/WhileLoopSpinsOnField.html index 86c79a3ffdc1..918d07712021 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/WhileLoopSpinsOnField.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/WhileLoopSpinsOnField.html @@ -6,6 +6,7 @@ extremely CPU intensive when little work is done inside the loop, such loops are likely have different semantics than intended, as the Java Memory Model allows such field accesses to be hoisted out of the loop, causing the loop to never complete even if another thread does change the field's value. +

    Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ZeroLengthArrayInitialization.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ZeroLengthArrayInitialization.html index d7b705c8a961..9dfaa8e94b12 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ZeroLengthArrayInitialization.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ZeroLengthArrayInitialization.html @@ -5,6 +5,7 @@ Java are non-modifiable, it is almost always possible to share zero-length array allocating new zero-length arrays. Such sharing may provide useful optimizations in program runtime or footprint. Note that this inspection does not report zero-length arrays allocated as static final fields, as it is assumed that those arrays are being used to implement array sharing. +

    Powered by InspectionGadgets diff --git a/plugins/android-designer/src/com/intellij/android/designer/componentTree/AndroidTreeDecorator.java b/plugins/android-designer/src/com/intellij/android/designer/componentTree/AndroidTreeDecorator.java index 635579b6909c..1c4787fe2304 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/componentTree/AndroidTreeDecorator.java +++ b/plugins/android-designer/src/com/intellij/android/designer/componentTree/AndroidTreeDecorator.java @@ -24,6 +24,7 @@ import com.intellij.designer.model.RadComponent; import com.intellij.designer.palette.DefaultPaletteItem; import com.intellij.designer.propertyTable.Property; import com.intellij.designer.propertyTable.PropertyTable; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.SimpleColoredComponent; import com.intellij.ui.SimpleTextAttributes; @@ -89,8 +90,21 @@ public final class AndroidTreeDecorator implements TreeComponentDecorator { } } + private static final Logger LOG = Logger.getInstance("#com.intellij.android.designer.componentTree"); + @Nullable private static String getPropertyValue(RadComponent component, String name) { + if (component.getProperties() == null) { + throw new NullPointerException("Component " + + component + + ", " + + component.getLayout() + + ", " + + component.getMetaModel().getTag() + + ", " + + component.getMetaModel().getTarget() + + " without properties"); + } Property property = PropertyTable.findProperty(component.getProperties(), name); if (property != null) { try { diff --git a/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java b/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java index c81060602c55..d8416ec45ce2 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java +++ b/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java @@ -16,6 +16,7 @@ package com.intellij.android.designer.designSurface; import com.android.ide.common.rendering.api.RenderSession; +import com.android.ide.common.rendering.api.ViewInfo; import com.android.ide.common.resources.configuration.*; import com.android.sdklib.IAndroidTarget; import com.intellij.android.designer.actions.ProfileAction; @@ -52,6 +53,7 @@ import com.intellij.psi.PsiManager; import com.intellij.psi.xml.XmlFile; import com.intellij.util.Alarm; import com.intellij.util.PsiNavigateUtil; +import com.intellij.util.ThrowableConsumer; import com.intellij.util.ThrowableRunnable; import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.android.maven.AndroidMavenUtil; @@ -170,11 +172,17 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { final ModelParser parser = new ModelParser(getProject(), myXmlFile); - createRenderer(parser.getLayoutXmlText(), new MyThrowable(), new ThrowableRunnable() { + createRenderer(parser.getLayoutXmlText(), new MyThrowable(), new ThrowableConsumer() { @Override - public void run() throws Throwable { - RootView rootView = new RootView(mySession.getImage(), 30, 20); - parser.updateRootComponent(mySession, rootView); + public void consume(RenderSession session) throws Throwable { + RootView rootView = new RootView(session.getImage(), 30, 20); + try { + parser.updateRootComponent(session, rootView); + } + catch (Throwable e) { + myRootComponent = parser.getRootComponent(); + throw e; + } RadViewComponent newRootComponent = parser.getRootComponent(); newRootComponent.setClientProperty(ModelParser.XML_FILE_KEY, myXmlFile); @@ -203,7 +211,9 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { }); } - private void createRenderer(final String layoutXmlText, final MyThrowable throwable, final ThrowableRunnable runnable) { + private void createRenderer(final String layoutXmlText, + final MyThrowable throwable, + final ThrowableConsumer runnable) { disposeRenderer(); ApplicationManager.getApplication().saveAll(); @@ -271,7 +281,7 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { throw new RenderingException(); } - mySession = result.getSession(); + final RenderSession session = mySession = result.getSession(); mySessionAlarm.cancelAllRequests(); ApplicationManager.getApplication().invokeLater(new Runnable() { @@ -280,7 +290,7 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { try { if (!getProject().isDisposed()) { hideProgress(); - runnable.run(); + runnable.consume(session); } } catch (Throwable e) { @@ -326,13 +336,13 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { return ModelParser.NO_ROOT_CONTENT; } }); - createRenderer(layoutXmlText, new MyThrowable(), new ThrowableRunnable() { + createRenderer(layoutXmlText, new MyThrowable(), new ThrowableConsumer() { @Override - public void run() throws Throwable { + public void consume(RenderSession session) throws Throwable { RadViewComponent rootComponent = (RadViewComponent)myRootComponent; RootView rootView = (RootView)rootComponent.getNativeComponent(); - rootView.setImage(mySession.getImage()); - ModelParser.updateRootComponent(rootComponent, mySession, rootView); + rootView.setImage(session.getImage()); + ModelParser.updateRootComponent(rootComponent, session, rootView); myParseTime = false; @@ -347,7 +357,10 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { private void removeNativeRoot() { if (myRootComponent != null) { - myLayeredPane.remove(((RadViewComponent)myRootComponent).getNativeComponent().getParent()); + Component component = ((RadViewComponent)myRootComponent).getNativeComponent(); + if (component != null) { + myLayeredPane.remove(component.getParent()); + } } } @@ -435,6 +448,15 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { builder.append(stream.toString()); } + if (info.myThrowable instanceof IndexOutOfBoundsException && myRootComponent != null && mySession != null) { + builder.append("\n-------- RadTree --------\n"); + ModelParser.printTree(builder, myRootComponent, 0); + builder.append("\n-------- ViewTree(").append(mySession.getRootViews().size()).append(") --------\n"); + for (ViewInfo viewInfo : mySession.getRootViews()) { + ModelParser.printTree(builder, viewInfo, 0); + } + } + info.myMessage = builder.toString(); } diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/ModelParser.java b/plugins/android-designer/src/com/intellij/android/designer/model/ModelParser.java index e67384ab57f7..19bf7ed3e681 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/ModelParser.java +++ b/plugins/android-designer/src/com/intellij/android/designer/model/ModelParser.java @@ -416,4 +416,26 @@ public class ModelParser extends XmlRecursiveElementVisitor { } } } + + public static void printTree(StringBuilder builder, RadComponent component, int level) { + for (int i = 0; i < level; i++) { + builder.append('\t'); + } + builder.append(component).append(" | ").append(component.getLayout()).append(" | ").append(component.getMetaModel().getTag()) + .append(" | ").append(component.getMetaModel().getTarget()).append(" = ").append(component.getChildren().size()).append("\n"); + for (RadComponent childComponent : component.getChildren()) { + printTree(builder, childComponent, level + 1); + } + } + + public static void printTree(StringBuilder builder, ViewInfo viewInfo, int level) { + for (int i = 0; i < level; i++) { + builder.append('\t'); + } + builder.append(viewInfo.getClassName()).append(" | ").append(viewInfo.getViewObject()).append(" | ") + .append(viewInfo.getLayoutParamsObject()).append(" = ").append(viewInfo.getChildren().size()).append("\n"); + for (ViewInfo childViewInfo : viewInfo.getChildren()) { + printTree(builder, childViewInfo, level + 1); + } + } } \ No newline at end of file diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidAutogenerator.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidAutogenerator.java index 3d0ce4836092..248fd15b45f3 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidAutogenerator.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidAutogenerator.java @@ -13,6 +13,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; @@ -375,7 +376,7 @@ public class AndroidAutogenerator { final List filesToDelete = new ArrayList(); for (final VirtualFile f : files) { - if (f != vFile && VfsUtilCore.isAncestor(genDir, f, true)) { + if (!Comparing.equal(f, vFile) && VfsUtilCore.isAncestor(genDir, f, true)) { filesToDelete.add(f); } } diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidCompileUtil.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidCompileUtil.java index b31a35ad3cf7..79c21de7a9ca 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidCompileUtil.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidCompileUtil.java @@ -175,7 +175,7 @@ public class AndroidCompileUtil { } for (Map.Entry entry : presentableFilesMap.entrySet()) { - if (file == entry.getValue()) { + if (Comparing.equal(file, entry.getValue())) { return entry.getKey().getUrl(); } } @@ -185,7 +185,7 @@ public class AndroidCompileUtil { private static void collectChildrenRecursively(@NotNull VirtualFile root, @NotNull VirtualFile anchor, @NotNull Collection result) { - if (root == anchor) { + if (Comparing.equal(root, anchor)) { return; } @@ -194,11 +194,11 @@ public class AndroidCompileUtil { return; } for (VirtualFile child : parent.getChildren()) { - if (child != anchor) { + if (!Comparing.equal(child, anchor)) { result.add(child); } } - if (parent != root) { + if (!Comparing.equal(parent, root)) { collectChildrenRecursively(root, parent, result); } } @@ -219,7 +219,7 @@ public class AndroidCompileUtil { if (contentEntry != null) { ExcludeFolder excludedFolder = null; for (ExcludeFolder folder : contentEntry.getExcludeFolders()) { - if (folder.getFile() == excludedRoot) { + if (Comparing.equal(folder.getFile(), excludedRoot)) { excludedFolder = folder; break; } @@ -280,7 +280,7 @@ public class AndroidCompileUtil { boolean markedAsSource = false; for (VirtualFile existingRoot : manager.getSourceRoots()) { - if (existingRoot == root) { + if (Comparing.equal(existingRoot, root)) { markedAsSource = true; } } @@ -301,7 +301,7 @@ public class AndroidCompileUtil { ((CompilerConfigurationImpl)CompilerConfiguration.getInstance(project)).getExcludedEntriesConfiguration(); for (ExcludeEntryDescription description : configuration.getExcludeEntryDescriptions()) { - if (description.getVirtualFile() == dir) { + if (Comparing.equal(description.getVirtualFile(), dir)) { return; } } @@ -477,7 +477,7 @@ public class AndroidCompileUtil { PsiFile psiFile = c.getContainingFile(); if (className.equals(FileUtil.getNameWithoutExtension(psiFile.getName()))) { VirtualFile virtualFile = psiFile.getVirtualFile(); - if (virtualFile != null && projectFileIndex.getSourceRootForFile(virtualFile) == sourceRoot) { + if (virtualFile != null && Comparing.equal(projectFileIndex.getSourceRootForFile(virtualFile), sourceRoot)) { final String path = virtualFile.getPath(); File f = new File(path); diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidIncludingCompiler.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidIncludingCompiler.java index 396542a80caa..ac9d297ef759 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidIncludingCompiler.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidIncludingCompiler.java @@ -23,6 +23,7 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.roots.ContentIterator; import com.intellij.openapi.roots.ModuleFileIndex; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; @@ -64,7 +65,7 @@ public class AndroidIncludingCompiler implements SourceGeneratingCompiler { VirtualFile[] srcRoots = ModuleRootManager.getInstance(depFacet.getModule()).getSourceRoots(); for (VirtualFile depSourceRoot : srcRoots) { - if (depSourceRoot != genSrcRoot) { + if (!Comparing.equal(depSourceRoot, genSrcRoot)) { VirtualFile file = depSourceRoot.findFileByRelativePath(generatedFileRelativePath); if (file != null) { return file; @@ -112,7 +113,7 @@ public class AndroidIncludingCompiler implements SourceGeneratingCompiler { VirtualFile[] srcRoots = ModuleRootManager.getInstance(depFacet.getModule()).getSourceRoots(); for (VirtualFile depSourceRoot : srcRoots) { - if (depSourceRoot != aptGenSrcRoot && depSourceRoot != aidlGenSrcRoot) { + if (!Comparing.equal(depSourceRoot, aptGenSrcRoot) && !Comparing.equal(depSourceRoot, aidlGenSrcRoot)) { collectCompilableFiles(module, depFacet.getModule(), context, depSourceRoot, qName2Item); } } diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidPackagingCompiler.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidPackagingCompiler.java index 3bc201520429..c100cdd996b4 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidPackagingCompiler.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidPackagingCompiler.java @@ -27,6 +27,7 @@ import com.intellij.openapi.roots.DependencyScope; import com.intellij.openapi.roots.ModuleOrderEntry; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VfsUtil; @@ -79,7 +80,7 @@ public class AndroidPackagingCompiler implements PackagingCompiler { VirtualFile resDir = facet != null ? AndroidRootUtil.getResourceDir(facet) : null; ModuleRootManager manager = ModuleRootManager.getInstance(module); for (VirtualFile sourceRoot : manager.getSourceRoots(includingTests)) { - if (resDir != sourceRoot) { + if (!Comparing.equal(resDir, sourceRoot)) { result.add(sourceRoot); } } diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidRenderscriptCompiler.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidRenderscriptCompiler.java index b1e6f16e6248..b554fa8de67f 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidRenderscriptCompiler.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidRenderscriptCompiler.java @@ -11,6 +11,7 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VfsUtilCore; @@ -254,7 +255,7 @@ public class AndroidRenderscriptCompiler implements SourceGeneratingCompiler { } final VirtualFile parent = sourceFile.getParent(); - if (parent == sourceRoot) { + if (Comparing.equal(parent, sourceRoot)) { return genFolder.getPath(); } diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidResourceFilesListener.java b/plugins/android/src/org/jetbrains/android/facet/AndroidResourceFilesListener.java index d356350f68e3..829e32356f86 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidResourceFilesListener.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidResourceFilesListener.java @@ -21,6 +21,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.vfs.*; import com.intellij.util.ui.update.MergingUpdateQueue; @@ -178,7 +179,7 @@ class AndroidResourceFilesListener extends VirtualFileAdapter { final VirtualFile resourceDir = AndroidRootUtil.getResourceDir(myFacet); - if (gp == resourceDir && + if (Comparing.equal(gp, resourceDir) && ResourceFolderType.VALUES.getName().equals(AndroidCommonUtils.getResourceTypeByDirName(parent.getName()))) { myFacet.getLocalResourceManager().invalidateAttributeDefinitions(); } @@ -186,7 +187,7 @@ class AndroidResourceFilesListener extends VirtualFileAdapter { final List modes = new ArrayList(); - if (AndroidAptCompiler.isToCompileModule(module, myFacet.getConfiguration()) && manifestFile == file) { + if (AndroidAptCompiler.isToCompileModule(module, myFacet.getConfiguration()) && Comparing.equal(manifestFile, file)) { final Manifest manifest = myFacet.getManifest(); final String aPackage = manifest != null ? manifest.getPackage().getValue() : null; @@ -200,19 +201,19 @@ class AndroidResourceFilesListener extends VirtualFileAdapter { if (file.getFileType() == AndroidIdlFileType.ourFileType) { VirtualFile sourceRoot = findSourceRoot(myModule, file); - if (sourceRoot != null && AndroidRootUtil.getAidlGenDir(myFacet) != sourceRoot) { + if (sourceRoot != null && !Comparing.equal(AndroidRootUtil.getAidlGenDir(myFacet), sourceRoot)) { modes.add(AndroidAutogeneratorMode.AIDL); } } if (file.getFileType() == AndroidRenderscriptFileType.INSTANCE) { final VirtualFile sourceRoot = findSourceRoot(myModule, file); - if (sourceRoot != null && AndroidRootUtil.getRenderscriptGenDir(myFacet) != sourceRoot) { + if (sourceRoot != null && !Comparing.equal(AndroidRootUtil.getRenderscriptGenDir(myFacet), sourceRoot)) { modes.add(AndroidAutogeneratorMode.RENDERSCRIPT); } } - if (manifestFile == file) { + if (Comparing.equal(manifestFile, file)) { modes.add(AndroidAutogeneratorMode.BUILDCONFIG); } return modes; @@ -223,8 +224,8 @@ class AndroidResourceFilesListener extends VirtualFileAdapter { if (update instanceof MyUpdate) { VirtualFile hisFile = ((MyUpdate)update).myEvent.getFile(); VirtualFile file = myEvent.getFile(); - - if (hisFile == file) { + + if (Comparing.equal(hisFile, file)) { return true; } diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidRootUtil.java b/plugins/android/src/org/jetbrains/android/facet/AndroidRootUtil.java index 15a04560ccb4..50dcad1b79ff 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidRootUtil.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidRootUtil.java @@ -25,6 +25,7 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; @@ -101,7 +102,7 @@ public class AndroidRootUtil { final VirtualFile moduleFileParentDir = LocalFileSystem.getInstance().findFileByPath(moduleFileParentDirPath); if (moduleFileParentDir != null) { for (VirtualFile contentRoot : contentRoots) { - if (contentRoot == moduleFileParentDir) { + if (Comparing.equal(contentRoot, moduleFileParentDir)) { root = contentRoot; } } diff --git a/plugins/android/src/org/jetbrains/android/inspections/lint/AndroidLintExternalAnnotator.java b/plugins/android/src/org/jetbrains/android/inspections/lint/AndroidLintExternalAnnotator.java index dee646c5cbaf..53f95528fae4 100644 --- a/plugins/android/src/org/jetbrains/android/inspections/lint/AndroidLintExternalAnnotator.java +++ b/plugins/android/src/org/jetbrains/android/inspections/lint/AndroidLintExternalAnnotator.java @@ -68,7 +68,7 @@ public class AndroidLintExternalAnnotator extends ExternalAnnotator 0) { - final VirtualFile contentRoot = files[0]; - final AndroidFacet facet = AndroidUtils.addAndroidFacet(rootModel.getModule(), contentRoot, myProjectType == ProjectType.LIBRARY); - - if (myProjectType == null) { - ImportDependenciesUtil.importDependencies(rootModel.getModule(), true); - return; - } - - final Project project = rootModel.getProject(); - final VirtualFile sourceRoot = findSourceRoot(rootModel); - - if (myProjectType == ProjectType.TEST) { - assert myTestedModule != null; - facet.getConfiguration().PACK_TEST_CODE = true; - ModuleOrderEntry entry = rootModel.addModuleOrderEntry(myTestedModule); - entry.setScope(DependencyScope.PROVIDED); - } - - StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() { - public void run() { - ApplicationManager.getApplication().invokeLater(new Runnable() { - public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - public void run() { - createProject(contentRoot, sourceRoot, facet); - } - }); - } - }); - } - }); - } - } - - private void createProject(VirtualFile contentRoot, VirtualFile sourceRoot, AndroidFacet facet) { - if (myProjectType == ProjectType.APPLICATION) { - createDirectoryStructure(contentRoot, sourceRoot, facet); - } - else { - createProjectByAndroidTool(contentRoot, sourceRoot, facet); - } - } - - private void createDirectoryStructure(VirtualFile contentRoot, VirtualFile sourceRoot, AndroidFacet facet) { - if (isHelloAndroid()) { - if (createProjectByAndroidTool(contentRoot, sourceRoot, facet)) { - return; - } - } - Project project = facet.getModule().getProject(); - createManifestFileAndAntFiles(project, contentRoot); - createResourcesAndLibs(project, contentRoot); - PsiDirectory sourceDir = sourceRoot != null ? PsiManager.getInstance(project).findDirectory(sourceRoot) : null; - createActivityAndSetupManifest(facet, sourceDir); - if (myTargetSelectionMode != null) { - addRunConfiguration(facet, myTargetSelectionMode, myPreferredAvd); - } - } - - @NotNull - private static String getAntProjectName(@NotNull String moduleName) { - StringBuilder result = new StringBuilder(); - for (int i = 0; i < moduleName.length(); i++) { - char c = moduleName.charAt(i); - if (!(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || Character.isDigit(c))) { - c = '_'; - } - result.append(c); - } - return result.toString(); - } - - private boolean createProjectByAndroidTool(final VirtualFile contentRoot, - final VirtualFile sourceRoot, - final AndroidFacet facet) { - - - File tempContentRoot = null; - - // todo: support custom non-empty source root - - if (sourceRoot != null && - sourceRoot.getChildren().length == 0 && - (sourceRoot.getParent() != contentRoot || !SdkConstants.FD_SOURCES.equals(sourceRoot.getName()))) { - try { - tempContentRoot = FileUtil.createTempDirectory("android_temp_content_root", "tmp"); - } - catch (IOException e) { - LOG.error(e); - } - } - - final Module module = facet.getModule(); - AndroidPlatform platform = AndroidPlatform.parse(mySdk); - - if (platform == null) { - Messages.showErrorDialog(module.getProject(), "Cannot parse Android SDK", CommonBundle.getErrorTitle()); - return true; - } - - final IAndroidTarget target = platform.getTarget(); - - final String androidToolPath = - platform.getSdkData().getLocation() + File.separator + AndroidCommonUtils.toolPath(SdkConstants.androidCmdName()); - - if (!new File(androidToolPath).exists()) { - return false; - } - - final GeneralCommandLine commandLine = new GeneralCommandLine(); - commandLine.setExePath(FileUtil.toSystemDependentName(androidToolPath)); - - commandLine.addParameter("create"); - - switch (myProjectType) { - case APPLICATION: - commandLine.addParameter("project"); - break; - case LIBRARY: - commandLine.addParameter("lib-project"); - break; - case TEST: - commandLine.addParameter("test-project"); - break; - } - - commandLine.addParameters("--name"); - commandLine.addParameter(getAntProjectName(module.getName())); - - commandLine.addParameters("--path"); - final String targetDirectoryPath = tempContentRoot != null ? tempContentRoot.getPath() : contentRoot.getPath(); - commandLine.addParameter(FileUtil.toSystemDependentName(targetDirectoryPath)); - - if (myProjectType == ProjectType.APPLICATION || myProjectType == ProjectType.LIBRARY) { - String apiLevel = target.hashString(); - commandLine.addParameter("--target"); - commandLine.addParameter(apiLevel); - commandLine.addParameter("--package"); - commandLine.addParameter(myPackageName); - } - - if (myProjectType == ProjectType.APPLICATION) { - commandLine.addParameter("--activity"); - commandLine.addParameter(myActivityName); - } - else if (myProjectType == ProjectType.TEST) { - String moduleDirPath = AndroidRootUtil.getModuleDirPath(myTestedModule); - assert moduleDirPath != null; - commandLine.addParameter("--main"); - commandLine.addParameter(FileUtil.toSystemDependentName(moduleDirPath)); - } - - final File finalTempContentRoot = tempContentRoot; - - ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { - @Override - public void run() { - final Project project = module.getProject(); - AndroidUtils.runExternalTool(commandLine, project); - - if (finalTempContentRoot != null) { - final File[] children = finalTempContentRoot.listFiles(); - - if (children != null) { - for (File child : children) { - if (SdkConstants.FD_SOURCES.equals(child.getName())) { - continue; - } - final File to = new File(contentRoot.getPath(), child.getName()); - - if (!FileUtil.moveDirWithContent(child, to)) { - LOG.error("Cannot move content from " + child.getPath() + " to " + to.getPath()); - } - } - } - - final File tempSourceRoot = new File(finalTempContentRoot, SdkConstants.FD_SOURCES); - if (tempSourceRoot.exists()) { - final File to = new File(sourceRoot.getPath()); - - if (!FileUtil.moveDirWithContent(tempSourceRoot, to)) { - LOG.error("Cannot move content from " + tempSourceRoot.getPath() + " to " + to.getPath()); - } - } - } - - StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() { - public void run() { - FileDocumentManager.getInstance().saveAllDocuments(); - } - }); - contentRoot.refresh(false, true); - - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - - if (contentRoot.findChild(SdkConstants.FN_ANDROID_MANIFEST_XML) == null) { - AndroidUtils.printMessageToConsole(project, "The project wasn't generated by 'android' tool.", - ConsoleViewContentType.ERROR_OUTPUT); - return; - } - - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - try { - if (project.isDisposed()) { - return; - } - if (myProjectType == ProjectType.APPLICATION) { - assignApplicationName(facet); - configureManifest(facet, target); - createChildDirectoryIfNotExist(project, contentRoot, SdkConstants.FD_ASSETS); - createChildDirectoryIfNotExist(project, contentRoot, SdkConstants.FD_NATIVE_LIBS); - } - else if (myProjectType == ProjectType.LIBRARY && myPackageName != null) { - final String[] dirs = myPackageName.split("\\."); - VirtualFile file = sourceRoot; - - for (String dir : dirs) { - if (file == null || dir.length() == 0) { - break; - } - final VirtualFile childDir = file.findChild(dir); - file = childDir != null - ? childDir - : file.createChildDirectory(project, dir); - } - } - } - catch (IOException e) { - LOG.error(e); - } - } - }); - - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - if (project.isDisposed() || facet.getModule().isDisposed()) { - return; - } - - if (myTargetSelectionMode != null) { - if (myProjectType == ProjectType.APPLICATION) { - addRunConfiguration(facet, myTargetSelectionMode, myPreferredAvd); - } - else if (myProjectType == ProjectType.TEST) { - addTestRunConfiguration(facet, myTargetSelectionMode, myPreferredAvd); - } - } - } - }); - - new ReformatCodeProcessor(project, module, false).run(); - } - }); - } - }); - return true; - } - - private static void configureManifest(@NotNull AndroidFacet facet, @NotNull IAndroidTarget target) { - final Manifest manifest = facet.getManifest(); - if (manifest == null) { - return; - } - - final XmlTag manifestTag = manifest.getXmlTag(); - if (manifestTag == null) { - return; - } - - XmlTag usesSdkTag = manifestTag.createChildTag("uses-sdk", "", null, false); - if (usesSdkTag != null) { - usesSdkTag = manifestTag.addSubTag(usesSdkTag, true); - usesSdkTag.setAttribute("minSdkVersion", SdkConstants.NS_RESOURCES, target.getVersion().getApiString()); - } - - final PsiFile manifestFile = manifestTag.getContainingFile(); - if (manifestFile != null) { - CodeStyleManager.getInstance(manifestFile.getProject()).reformat(manifestFile); - } - } - - private void assignApplicationName(AndroidFacet facet) { - if (myApplicationName == null || myApplicationName.length() == 0) { - return; - } - - final LocalResourceManager manager = facet.getLocalResourceManager(); - ResourceElement appNameResElement = null; - final String appNameResource = "app_name"; - - for (ResourceElement resElement : manager.getValueResources("string")) { - if (appNameResource.equals(resElement.getName().getValue())) { - appNameResElement = resElement; - } - } - - final String normalizedAppName = AndroidResourceUtil.normalizeXmlResourceValue(myApplicationName.replace("\\", "\\\\")); - - if (appNameResElement == null) { - final String fileName = AndroidResourceUtil.getDefaultResourceFileName(ResourceType.STRING); - assert fileName != null; - AndroidResourceUtil.createValueResource(facet.getModule(), appNameResource, ResourceType.STRING, fileName, Collections - .singletonList(AndroidConstants.FD_RES_VALUES), normalizedAppName); - } - else { - appNameResElement.setStringValue(normalizedAppName); - } - - final Manifest manifest = facet.getManifest(); - - if (manifest != null) { - manifest.getApplication().getLabel().setValue(ResourceValue.referenceTo('@', null, "string", appNameResource)); - } - } - - private void createManifestFileAndAntFiles(Project project, VirtualFile contentRoot) { - VirtualFile existingManifestFile = contentRoot.findChild(FN_ANDROID_MANIFEST_XML); - if (existingManifestFile != null) { - return; - } - try { - AndroidFileTemplateProvider - .createFromTemplate(project, contentRoot, AndroidFileTemplateProvider.ANDROID_MANIFEST_TEMPLATE, FN_ANDROID_MANIFEST_XML); - - AndroidPlatform platform = AndroidPlatform.parse(mySdk); - - if (platform == null) { - Messages.showErrorDialog(project, "Cannot parse Android SDK: 'default.properties' won't be generated", CommonBundle.getErrorTitle()); - return; - } - - Properties properties = FileTemplateManager.getInstance().getDefaultProperties(project); - properties.setProperty("TARGET", platform.getTarget().hashString()); - AndroidFileTemplateProvider.createFromTemplate(project, contentRoot, AndroidFileTemplateProvider.DEFAULT_PROPERTIES_TEMPLATE, - SdkConstants.FN_PROJECT_PROPERTIES, properties); - } - catch (Exception e) { - LOG.error(e); - } - } - - private void addRunConfiguration(@NotNull AndroidFacet facet, - @NotNull TargetSelectionMode targetSelectionMode, - @Nullable String targetAvd) { - String activityClass; - if (isHelloAndroid()) { - activityClass = myPackageName + '.' + myActivityName; - } - else { - activityClass = null; - } - Module module = facet.getModule(); - AndroidUtils.addRunConfiguration(facet, activityClass, false, targetSelectionMode, targetAvd); - } - - private static void addTestRunConfiguration(final AndroidFacet facet, @NotNull TargetSelectionMode mode, @Nullable String preferredAvd) { - Project project = facet.getModule().getProject(); - RunManagerEx runManager = RunManagerEx.getInstanceEx(project); - Module module = facet.getModule(); - RunnerAndConfigurationSettings settings = runManager - .createRunConfiguration(module.getName(), AndroidTestRunConfigurationType.getInstance().getFactory()); - - AndroidTestRunConfiguration configuration = (AndroidTestRunConfiguration)settings.getConfiguration(); - configuration.setModule(module); - configuration.setTargetSelectionMode(mode); - if (preferredAvd != null) { - configuration.PREFERRED_AVD = preferredAvd; - } - - runManager.addConfiguration(settings, false); - runManager.setActiveConfiguration(settings); - } - - private boolean isHelloAndroid() { - return myActivityName.length() > 0; - } - - @Nullable - private static VirtualFile findSourceRoot(ModifiableRootModel model) { - VirtualFile genSourceRoot = AndroidRootUtil.getStandartGenDir(model.getModule()); - for (VirtualFile root : model.getSourceRoots()) { - if (root != genSourceRoot) { - return root; - } - } - return null; - } - - @Nullable - private static PsiDirectory createPackageIfPossible(final PsiDirectory sourceDir, String packageName) { - if (sourceDir != null) { - final String[] ids = packageName.split("\\."); - return ApplicationManager.getApplication().runWriteAction(new Computable() { - public PsiDirectory compute() { - PsiDirectory dir = sourceDir; - for (String id : ids) { - PsiDirectory child = dir.findSubdirectory(id); - dir = child == null ? dir.createSubdirectory(id) : child; - } - return dir; - } - }); - } - return null; - } - - private void createActivityAndSetupManifest(final AndroidFacet facet, final PsiDirectory sourceDir) { - if (myPackageName != null) { - CommandProcessor.getInstance().executeCommand(facet.getModule().getProject(), new ExternalChangeAction() { - public void run() { - Runnable action = new Runnable() { - public void run() { - PsiDirectory packageDir = createPackageIfPossible(sourceDir, myPackageName); - if (packageDir == null) return; - final Manifest manifest = facet.getManifest(); - if (manifest != null) { - manifest.getPackage().setValue(myPackageName); - final Project project = facet.getModule().getProject(); - StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() { - public void run() { - FileDocumentManager.getInstance().saveAllDocuments(); - } - }); - - assignApplicationName(facet); - - final AndroidPlatform platform = AndroidPlatform.parse(mySdk); - if (platform != null) { - configureManifest(facet, platform.getTarget()); - } - } - } - }; - ApplicationManager.getApplication().runWriteAction(action); - } - }, AndroidBundle.message("build.android.module.process.title"), null); - } - } - - private void createResourcesAndLibs(final Project project, final VirtualFile rootDir) { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - public void run() { - try { - createChildDirectoryIfNotExist(project, rootDir, SdkConstants.FD_ASSETS); - createChildDirectoryIfNotExist(project, rootDir, SdkConstants.FD_NATIVE_LIBS); - VirtualFile resDir = createChildDirectoryIfNotExist(project, rootDir, SdkConstants.FD_RES); - VirtualFile drawableDir = createChildDirectoryIfNotExist(project, resDir, AndroidConstants.FD_RES_DRAWABLE); - createFileFromResource(project, drawableDir, "icon.png", "/icons/androidLarge.png"); - if (isHelloAndroid()) { - VirtualFile valuesDir = createChildDirectoryIfNotExist(project, resDir, AndroidConstants.FD_RES_VALUES); - createFileFromResource(project, valuesDir, "strings.xml", "res/values/strings.xml"); - VirtualFile layoutDir = AndroidUtils.createChildDirectoryIfNotExist(project, resDir, AndroidConstants.FD_RES_LAYOUT); - createFileFromResource(project, layoutDir, "main.xml", "res/layout/main.xml"); - } - } - catch (IOException e) { - LOG.error(e); - } - } - }); - } - - private static void createFileFromResource(Project project, VirtualFile drawableDir, String name, String resourceFilePath) - throws IOException { - if (drawableDir.findChild(name) != null) { - return; - } - VirtualFile resFile = drawableDir.createChildData(project, name); - InputStream stream = AndroidModuleBuilder.class.getResourceAsStream(resourceFilePath); - try { - byte[] bytes = FileUtil.adaptiveLoadBytes(stream); - resFile.setBinaryContent(bytes); - } - finally { - stream.close(); - } - } - - public void setProjectType(ProjectType projectType) { - myProjectType = projectType; - } - - public void setActivityName(String activityName) { - myActivityName = activityName; - } - - public void setApplicationName(String applicationName) { - myApplicationName = applicationName; - } - - public void setPackageName(String packageName) { - myPackageName = packageName; - } - - public void setSdk(Sdk sdk) { - mySdk = sdk; - } - - public ModuleType getModuleType() { - return StdModuleTypes.JAVA; - } - - public void setTestedModule(Module module) { - myTestedModule = module; - } - - public void setTargetSelectionMode(TargetSelectionMode targetSelectionMode) { - myTargetSelectionMode = targetSelectionMode; - } - - public void setPreferredAvd(String preferredAvd) { - myPreferredAvd = preferredAvd; - } - - @Override - public ModuleWizardStep[] createWizardSteps(WizardContext wizardContext, ModulesProvider modulesProvider) { - List steps = new ArrayList(); - ProjectWizardStepFactory factory = ProjectWizardStepFactory.getInstance(); - steps.add(factory.createSourcePathsStep(wizardContext, this, null, "reference.dialogs.new.project.fromScratch.source")); - - if (!hasAppropriateJdk()) { - steps.add(new ProjectJdkForModuleStep(wizardContext, JavaSdk.getInstance()) { - @Override - public void updateDataModel() { - // do nothing - } - - @Override - public boolean validate() { - for (Object o : getAllJdks()) { - if (o instanceof Sdk) { - Sdk sdk = (Sdk)o; - if (AndroidSdkUtils.isApplicableJdk(sdk)) { - return true; - } - } - } - Messages.showErrorDialog(AndroidBundle.message("no.jdk.error"), CommonBundle.getErrorTitle()); - return false; - } - }); - } - - steps.add(new AndroidModuleWizardStep(this, wizardContext)); - return steps.toArray(new ModuleWizardStep[steps.size()]); - } - - public Icon getBigIcon() { - return AndroidUtils.ANDROID_ICON_24; - } - - public String getDescription() { - return AndroidBundle.message("android.module.type.description"); - } - - public String getPresentableName() { - return AndroidBundle.message("android.module.type.name"); - } - - @Override - public String getBuilderId() { - return getClass().getName(); - } - - private static boolean hasAppropriateJdk() { - for (Sdk sdk : ProjectJdkTable.getInstance().getAllJdks()) { - if (AndroidSdkUtils.isApplicableJdk(sdk)) { - return true; - } - } - return false; - } -} +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.android.newProject; + +import com.android.AndroidConstants; +import com.android.resources.ResourceType; +import com.android.sdklib.IAndroidTarget; +import com.android.sdklib.SdkConstants; +import com.intellij.CommonBundle; +import com.intellij.codeInsight.actions.ReformatCodeProcessor; +import com.intellij.execution.RunManagerEx; +import com.intellij.execution.RunnerAndConfigurationSettings; +import com.intellij.execution.configurations.GeneralCommandLine; +import com.intellij.execution.ui.ConsoleViewContentType; +import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.ide.util.projectWizard.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.module.StdModuleTypes; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.JavaSdk; +import com.intellij.openapi.projectRoots.ProjectJdkTable; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.ui.configuration.ModulesProvider; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.ExternalChangeAction; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.xml.XmlTag; +import org.jetbrains.android.AndroidFileTemplateProvider; +import org.jetbrains.android.dom.manifest.Manifest; +import org.jetbrains.android.dom.resources.ResourceElement; +import org.jetbrains.android.dom.resources.ResourceValue; +import org.jetbrains.android.facet.AndroidFacet; +import org.jetbrains.android.facet.AndroidRootUtil; +import org.jetbrains.android.importDependencies.ImportDependenciesUtil; +import org.jetbrains.android.resourceManagers.LocalResourceManager; +import org.jetbrains.android.run.TargetSelectionMode; +import org.jetbrains.android.run.testing.AndroidTestRunConfiguration; +import org.jetbrains.android.run.testing.AndroidTestRunConfigurationType; +import org.jetbrains.android.sdk.AndroidPlatform; +import org.jetbrains.android.sdk.AndroidSdkUtils; +import org.jetbrains.android.util.AndroidBundle; +import org.jetbrains.android.util.AndroidCommonUtils; +import org.jetbrains.android.util.AndroidResourceUtil; +import org.jetbrains.android.util.AndroidUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Properties; + +import static com.android.sdklib.SdkConstants.FN_ANDROID_MANIFEST_XML; +import static org.jetbrains.android.util.AndroidUtils.createChildDirectoryIfNotExist; + +/** + * @author Eugene.Kudelevsky + */ +public class AndroidModuleBuilder extends JavaModuleBuilder { + private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.newProject.AndroidModuleBuilder"); + + private String myPackageName; + private String myApplicationName; + private String myActivityName; + private ProjectType myProjectType; + private Module myTestedModule; + private Sdk mySdk; + private TargetSelectionMode myTargetSelectionMode; + private String myPreferredAvd; + + public void setupRootModel(final ModifiableRootModel rootModel) throws ConfigurationException { + super.setupRootModel(rootModel); + + rootModel.setSdk(mySdk); + + final LanguageLevelModuleExtension moduleExt = rootModel.getModuleExtension(LanguageLevelModuleExtension.class); + + if (moduleExt != null) { + LanguageLevel languageLevel = moduleExt.getLanguageLevel(); + if (languageLevel == null) { + final LanguageLevelProjectExtension projectExt = LanguageLevelProjectExtension.getInstance(rootModel.getProject()); + if (projectExt != null) { + languageLevel = projectExt.getLanguageLevel(); + } + } + if (languageLevel == LanguageLevel.JDK_1_3) { + moduleExt.setLanguageLevel(LanguageLevel.JDK_1_5); + } + } + + VirtualFile[] files = rootModel.getContentRoots(); + if (files.length > 0) { + final VirtualFile contentRoot = files[0]; + final AndroidFacet facet = AndroidUtils.addAndroidFacet(rootModel.getModule(), contentRoot, myProjectType == ProjectType.LIBRARY); + + if (myProjectType == null) { + ImportDependenciesUtil.importDependencies(rootModel.getModule(), true); + return; + } + + final Project project = rootModel.getProject(); + final VirtualFile sourceRoot = findSourceRoot(rootModel); + + if (myProjectType == ProjectType.TEST) { + assert myTestedModule != null; + facet.getConfiguration().PACK_TEST_CODE = true; + ModuleOrderEntry entry = rootModel.addModuleOrderEntry(myTestedModule); + entry.setScope(DependencyScope.PROVIDED); + } + + StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() { + public void run() { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + createProject(contentRoot, sourceRoot, facet); + } + }); + } + }); + } + }); + } + } + + private void createProject(VirtualFile contentRoot, VirtualFile sourceRoot, AndroidFacet facet) { + if (myProjectType == ProjectType.APPLICATION) { + createDirectoryStructure(contentRoot, sourceRoot, facet); + } + else { + createProjectByAndroidTool(contentRoot, sourceRoot, facet); + } + } + + private void createDirectoryStructure(VirtualFile contentRoot, VirtualFile sourceRoot, AndroidFacet facet) { + if (isHelloAndroid()) { + if (createProjectByAndroidTool(contentRoot, sourceRoot, facet)) { + return; + } + } + Project project = facet.getModule().getProject(); + createManifestFileAndAntFiles(project, contentRoot); + createResourcesAndLibs(project, contentRoot); + PsiDirectory sourceDir = sourceRoot != null ? PsiManager.getInstance(project).findDirectory(sourceRoot) : null; + createActivityAndSetupManifest(facet, sourceDir); + if (myTargetSelectionMode != null) { + addRunConfiguration(facet, myTargetSelectionMode, myPreferredAvd); + } + } + + @NotNull + private static String getAntProjectName(@NotNull String moduleName) { + StringBuilder result = new StringBuilder(); + for (int i = 0; i < moduleName.length(); i++) { + char c = moduleName.charAt(i); + if (!(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || Character.isDigit(c))) { + c = '_'; + } + result.append(c); + } + return result.toString(); + } + + private boolean createProjectByAndroidTool(final VirtualFile contentRoot, + final VirtualFile sourceRoot, + final AndroidFacet facet) { + + + File tempContentRoot = null; + + // todo: support custom non-empty source root + + if (sourceRoot != null && + sourceRoot.getChildren().length == 0 && + (!Comparing.equal(sourceRoot.getParent(), contentRoot) || !SdkConstants.FD_SOURCES.equals(sourceRoot.getName()))) { + try { + tempContentRoot = FileUtil.createTempDirectory("android_temp_content_root", "tmp"); + } + catch (IOException e) { + LOG.error(e); + } + } + + final Module module = facet.getModule(); + AndroidPlatform platform = AndroidPlatform.parse(mySdk); + + if (platform == null) { + Messages.showErrorDialog(module.getProject(), "Cannot parse Android SDK", CommonBundle.getErrorTitle()); + return true; + } + + final IAndroidTarget target = platform.getTarget(); + + final String androidToolPath = + platform.getSdkData().getLocation() + File.separator + AndroidCommonUtils.toolPath(SdkConstants.androidCmdName()); + + if (!new File(androidToolPath).exists()) { + return false; + } + + final GeneralCommandLine commandLine = new GeneralCommandLine(); + commandLine.setExePath(FileUtil.toSystemDependentName(androidToolPath)); + + commandLine.addParameter("create"); + + switch (myProjectType) { + case APPLICATION: + commandLine.addParameter("project"); + break; + case LIBRARY: + commandLine.addParameter("lib-project"); + break; + case TEST: + commandLine.addParameter("test-project"); + break; + } + + commandLine.addParameters("--name"); + commandLine.addParameter(getAntProjectName(module.getName())); + + commandLine.addParameters("--path"); + final String targetDirectoryPath = tempContentRoot != null ? tempContentRoot.getPath() : contentRoot.getPath(); + commandLine.addParameter(FileUtil.toSystemDependentName(targetDirectoryPath)); + + if (myProjectType == ProjectType.APPLICATION || myProjectType == ProjectType.LIBRARY) { + String apiLevel = target.hashString(); + commandLine.addParameter("--target"); + commandLine.addParameter(apiLevel); + commandLine.addParameter("--package"); + commandLine.addParameter(myPackageName); + } + + if (myProjectType == ProjectType.APPLICATION) { + commandLine.addParameter("--activity"); + commandLine.addParameter(myActivityName); + } + else if (myProjectType == ProjectType.TEST) { + String moduleDirPath = AndroidRootUtil.getModuleDirPath(myTestedModule); + assert moduleDirPath != null; + commandLine.addParameter("--main"); + commandLine.addParameter(FileUtil.toSystemDependentName(moduleDirPath)); + } + + final File finalTempContentRoot = tempContentRoot; + + ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + @Override + public void run() { + final Project project = module.getProject(); + AndroidUtils.runExternalTool(commandLine, project); + + if (finalTempContentRoot != null) { + final File[] children = finalTempContentRoot.listFiles(); + + if (children != null) { + for (File child : children) { + if (SdkConstants.FD_SOURCES.equals(child.getName())) { + continue; + } + final File to = new File(contentRoot.getPath(), child.getName()); + + if (!FileUtil.moveDirWithContent(child, to)) { + LOG.error("Cannot move content from " + child.getPath() + " to " + to.getPath()); + } + } + } + + final File tempSourceRoot = new File(finalTempContentRoot, SdkConstants.FD_SOURCES); + if (tempSourceRoot.exists()) { + final File to = new File(sourceRoot.getPath()); + + if (!FileUtil.moveDirWithContent(tempSourceRoot, to)) { + LOG.error("Cannot move content from " + tempSourceRoot.getPath() + " to " + to.getPath()); + } + } + } + + StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() { + public void run() { + FileDocumentManager.getInstance().saveAllDocuments(); + } + }); + contentRoot.refresh(false, true); + + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + + if (contentRoot.findChild(SdkConstants.FN_ANDROID_MANIFEST_XML) == null) { + AndroidUtils.printMessageToConsole(project, "The project wasn't generated by 'android' tool.", + ConsoleViewContentType.ERROR_OUTPUT); + return; + } + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + try { + if (project.isDisposed()) { + return; + } + if (myProjectType == ProjectType.APPLICATION) { + assignApplicationName(facet); + configureManifest(facet, target); + createChildDirectoryIfNotExist(project, contentRoot, SdkConstants.FD_ASSETS); + createChildDirectoryIfNotExist(project, contentRoot, SdkConstants.FD_NATIVE_LIBS); + } + else if (myProjectType == ProjectType.LIBRARY && myPackageName != null) { + final String[] dirs = myPackageName.split("\\."); + VirtualFile file = sourceRoot; + + for (String dir : dirs) { + if (file == null || dir.length() == 0) { + break; + } + final VirtualFile childDir = file.findChild(dir); + file = childDir != null + ? childDir + : file.createChildDirectory(project, dir); + } + } + } + catch (IOException e) { + LOG.error(e); + } + } + }); + + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + if (project.isDisposed() || facet.getModule().isDisposed()) { + return; + } + + if (myTargetSelectionMode != null) { + if (myProjectType == ProjectType.APPLICATION) { + addRunConfiguration(facet, myTargetSelectionMode, myPreferredAvd); + } + else if (myProjectType == ProjectType.TEST) { + addTestRunConfiguration(facet, myTargetSelectionMode, myPreferredAvd); + } + } + } + }); + + new ReformatCodeProcessor(project, module, false).run(); + } + }); + } + }); + return true; + } + + private static void configureManifest(@NotNull AndroidFacet facet, @NotNull IAndroidTarget target) { + final Manifest manifest = facet.getManifest(); + if (manifest == null) { + return; + } + + final XmlTag manifestTag = manifest.getXmlTag(); + if (manifestTag == null) { + return; + } + + XmlTag usesSdkTag = manifestTag.createChildTag("uses-sdk", "", null, false); + if (usesSdkTag != null) { + usesSdkTag = manifestTag.addSubTag(usesSdkTag, true); + usesSdkTag.setAttribute("minSdkVersion", SdkConstants.NS_RESOURCES, target.getVersion().getApiString()); + } + + final PsiFile manifestFile = manifestTag.getContainingFile(); + if (manifestFile != null) { + CodeStyleManager.getInstance(manifestFile.getProject()).reformat(manifestFile); + } + } + + private void assignApplicationName(AndroidFacet facet) { + if (myApplicationName == null || myApplicationName.length() == 0) { + return; + } + + final LocalResourceManager manager = facet.getLocalResourceManager(); + ResourceElement appNameResElement = null; + final String appNameResource = "app_name"; + + for (ResourceElement resElement : manager.getValueResources("string")) { + if (appNameResource.equals(resElement.getName().getValue())) { + appNameResElement = resElement; + } + } + + final String normalizedAppName = AndroidResourceUtil.normalizeXmlResourceValue(myApplicationName.replace("\\", "\\\\")); + + if (appNameResElement == null) { + final String fileName = AndroidResourceUtil.getDefaultResourceFileName(ResourceType.STRING); + assert fileName != null; + AndroidResourceUtil.createValueResource(facet.getModule(), appNameResource, ResourceType.STRING, fileName, Collections + .singletonList(AndroidConstants.FD_RES_VALUES), normalizedAppName); + } + else { + appNameResElement.setStringValue(normalizedAppName); + } + + final Manifest manifest = facet.getManifest(); + + if (manifest != null) { + manifest.getApplication().getLabel().setValue(ResourceValue.referenceTo('@', null, "string", appNameResource)); + } + } + + private void createManifestFileAndAntFiles(Project project, VirtualFile contentRoot) { + VirtualFile existingManifestFile = contentRoot.findChild(FN_ANDROID_MANIFEST_XML); + if (existingManifestFile != null) { + return; + } + try { + AndroidFileTemplateProvider + .createFromTemplate(project, contentRoot, AndroidFileTemplateProvider.ANDROID_MANIFEST_TEMPLATE, FN_ANDROID_MANIFEST_XML); + + AndroidPlatform platform = AndroidPlatform.parse(mySdk); + + if (platform == null) { + Messages.showErrorDialog(project, "Cannot parse Android SDK: 'default.properties' won't be generated", CommonBundle.getErrorTitle()); + return; + } + + Properties properties = FileTemplateManager.getInstance().getDefaultProperties(project); + properties.setProperty("TARGET", platform.getTarget().hashString()); + AndroidFileTemplateProvider.createFromTemplate(project, contentRoot, AndroidFileTemplateProvider.DEFAULT_PROPERTIES_TEMPLATE, + SdkConstants.FN_PROJECT_PROPERTIES, properties); + } + catch (Exception e) { + LOG.error(e); + } + } + + private void addRunConfiguration(@NotNull AndroidFacet facet, + @NotNull TargetSelectionMode targetSelectionMode, + @Nullable String targetAvd) { + String activityClass; + if (isHelloAndroid()) { + activityClass = myPackageName + '.' + myActivityName; + } + else { + activityClass = null; + } + Module module = facet.getModule(); + AndroidUtils.addRunConfiguration(facet, activityClass, false, targetSelectionMode, targetAvd); + } + + private static void addTestRunConfiguration(final AndroidFacet facet, @NotNull TargetSelectionMode mode, @Nullable String preferredAvd) { + Project project = facet.getModule().getProject(); + RunManagerEx runManager = RunManagerEx.getInstanceEx(project); + Module module = facet.getModule(); + RunnerAndConfigurationSettings settings = runManager + .createRunConfiguration(module.getName(), AndroidTestRunConfigurationType.getInstance().getFactory()); + + AndroidTestRunConfiguration configuration = (AndroidTestRunConfiguration)settings.getConfiguration(); + configuration.setModule(module); + configuration.setTargetSelectionMode(mode); + if (preferredAvd != null) { + configuration.PREFERRED_AVD = preferredAvd; + } + + runManager.addConfiguration(settings, false); + runManager.setActiveConfiguration(settings); + } + + private boolean isHelloAndroid() { + return myActivityName.length() > 0; + } + + @Nullable + private static VirtualFile findSourceRoot(ModifiableRootModel model) { + VirtualFile genSourceRoot = AndroidRootUtil.getStandartGenDir(model.getModule()); + for (VirtualFile root : model.getSourceRoots()) { + if (!Comparing.equal(root, genSourceRoot)) { + return root; + } + } + return null; + } + + @Nullable + private static PsiDirectory createPackageIfPossible(final PsiDirectory sourceDir, String packageName) { + if (sourceDir != null) { + final String[] ids = packageName.split("\\."); + return ApplicationManager.getApplication().runWriteAction(new Computable() { + public PsiDirectory compute() { + PsiDirectory dir = sourceDir; + for (String id : ids) { + PsiDirectory child = dir.findSubdirectory(id); + dir = child == null ? dir.createSubdirectory(id) : child; + } + return dir; + } + }); + } + return null; + } + + private void createActivityAndSetupManifest(final AndroidFacet facet, final PsiDirectory sourceDir) { + if (myPackageName != null) { + CommandProcessor.getInstance().executeCommand(facet.getModule().getProject(), new ExternalChangeAction() { + public void run() { + Runnable action = new Runnable() { + public void run() { + PsiDirectory packageDir = createPackageIfPossible(sourceDir, myPackageName); + if (packageDir == null) return; + final Manifest manifest = facet.getManifest(); + if (manifest != null) { + manifest.getPackage().setValue(myPackageName); + final Project project = facet.getModule().getProject(); + StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() { + public void run() { + FileDocumentManager.getInstance().saveAllDocuments(); + } + }); + + assignApplicationName(facet); + + final AndroidPlatform platform = AndroidPlatform.parse(mySdk); + if (platform != null) { + configureManifest(facet, platform.getTarget()); + } + } + } + }; + ApplicationManager.getApplication().runWriteAction(action); + } + }, AndroidBundle.message("build.android.module.process.title"), null); + } + } + + private void createResourcesAndLibs(final Project project, final VirtualFile rootDir) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + try { + createChildDirectoryIfNotExist(project, rootDir, SdkConstants.FD_ASSETS); + createChildDirectoryIfNotExist(project, rootDir, SdkConstants.FD_NATIVE_LIBS); + VirtualFile resDir = createChildDirectoryIfNotExist(project, rootDir, SdkConstants.FD_RES); + VirtualFile drawableDir = createChildDirectoryIfNotExist(project, resDir, AndroidConstants.FD_RES_DRAWABLE); + createFileFromResource(project, drawableDir, "icon.png", "/icons/androidLarge.png"); + if (isHelloAndroid()) { + VirtualFile valuesDir = createChildDirectoryIfNotExist(project, resDir, AndroidConstants.FD_RES_VALUES); + createFileFromResource(project, valuesDir, "strings.xml", "res/values/strings.xml"); + VirtualFile layoutDir = AndroidUtils.createChildDirectoryIfNotExist(project, resDir, AndroidConstants.FD_RES_LAYOUT); + createFileFromResource(project, layoutDir, "main.xml", "res/layout/main.xml"); + } + } + catch (IOException e) { + LOG.error(e); + } + } + }); + } + + private static void createFileFromResource(Project project, VirtualFile drawableDir, String name, String resourceFilePath) + throws IOException { + if (drawableDir.findChild(name) != null) { + return; + } + VirtualFile resFile = drawableDir.createChildData(project, name); + InputStream stream = AndroidModuleBuilder.class.getResourceAsStream(resourceFilePath); + try { + byte[] bytes = FileUtil.adaptiveLoadBytes(stream); + resFile.setBinaryContent(bytes); + } + finally { + stream.close(); + } + } + + public void setProjectType(ProjectType projectType) { + myProjectType = projectType; + } + + public void setActivityName(String activityName) { + myActivityName = activityName; + } + + public void setApplicationName(String applicationName) { + myApplicationName = applicationName; + } + + public void setPackageName(String packageName) { + myPackageName = packageName; + } + + public void setSdk(Sdk sdk) { + mySdk = sdk; + } + + public ModuleType getModuleType() { + return StdModuleTypes.JAVA; + } + + public void setTestedModule(Module module) { + myTestedModule = module; + } + + public void setTargetSelectionMode(TargetSelectionMode targetSelectionMode) { + myTargetSelectionMode = targetSelectionMode; + } + + public void setPreferredAvd(String preferredAvd) { + myPreferredAvd = preferredAvd; + } + + @Override + public ModuleWizardStep[] createWizardSteps(WizardContext wizardContext, ModulesProvider modulesProvider) { + List steps = new ArrayList(); + ProjectWizardStepFactory factory = ProjectWizardStepFactory.getInstance(); + steps.add(factory.createSourcePathsStep(wizardContext, this, null, "reference.dialogs.new.project.fromScratch.source")); + + if (!hasAppropriateJdk()) { + steps.add(new ProjectJdkForModuleStep(wizardContext, JavaSdk.getInstance()) { + @Override + public void updateDataModel() { + // do nothing + } + + @Override + public boolean validate() { + for (Object o : getAllJdks()) { + if (o instanceof Sdk) { + Sdk sdk = (Sdk)o; + if (AndroidSdkUtils.isApplicableJdk(sdk)) { + return true; + } + } + } + Messages.showErrorDialog(AndroidBundle.message("no.jdk.error"), CommonBundle.getErrorTitle()); + return false; + } + }); + } + + steps.add(new AndroidModuleWizardStep(this, wizardContext)); + return steps.toArray(new ModuleWizardStep[steps.size()]); + } + + public Icon getBigIcon() { + return AndroidUtils.ANDROID_ICON_24; + } + + public String getDescription() { + return AndroidBundle.message("android.module.type.description"); + } + + public String getPresentableName() { + return AndroidBundle.message("android.module.type.name"); + } + + @Override + public String getBuilderId() { + return getClass().getName(); + } + + private static boolean hasAppropriateJdk() { + for (Sdk sdk : ProjectJdkTable.getInstance().getAllJdks()) { + if (AndroidSdkUtils.isApplicableJdk(sdk)) { + return true; + } + } + return false; + } +} diff --git a/plugins/android/src/org/jetbrains/android/uipreview/RenderUtil.java b/plugins/android/src/org/jetbrains/android/uipreview/RenderUtil.java index cfd48c23c2db..f34d62e9614c 100644 --- a/plugins/android/src/org/jetbrains/android/uipreview/RenderUtil.java +++ b/plugins/android/src/org/jetbrains/android/uipreview/RenderUtil.java @@ -29,6 +29,7 @@ import com.intellij.openapi.roots.ui.configuration.ClasspathEditor; import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator; import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; @@ -498,7 +499,7 @@ public class RenderUtil { final String filePath = FileUtil.toSystemIndependentName(fileWrapper.getOsLocation()); vFile = LocalFileSystem.getInstance().findFileByPath(filePath); - if (vFile != null && vFile == layoutXmlFile && layoutXmlFileText != null) { + if (vFile != null && Comparing.equal(vFile, layoutXmlFile) && layoutXmlFileText != null) { resFolder.processFile(new MyFileWrapper(layoutXmlFileText, childRes), ResourceDeltaKind.ADDED, scanningContext); } else { diff --git a/plugins/android/src/org/jetbrains/android/util/AndroidUtils.java b/plugins/android/src/org/jetbrains/android/util/AndroidUtils.java index 9bfafc939fd3..82207c492b93 100644 --- a/plugins/android/src/org/jetbrains/android/util/AndroidUtils.java +++ b/plugins/android/src/org/jetbrains/android/util/AndroidUtils.java @@ -52,6 +52,7 @@ import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.Key; @@ -183,7 +184,7 @@ public class AndroidUtils { final List packages = new ArrayList(); file = file.getParent(); - while (file != null && projectDir != file && !sourceRoots.contains(file)) { + while (file != null && !Comparing.equal(projectDir, file) && !sourceRoots.contains(file)) { packages.add(file.getName()); file = file.getParent(); } diff --git a/plugins/ant/src/com/intellij/lang/ant/dom/AntDomPattern.java b/plugins/ant/src/com/intellij/lang/ant/dom/AntDomPattern.java index e5fa1679a331..0b73ad56dff8 100644 --- a/plugins/ant/src/com/intellij/lang/ant/dom/AntDomPattern.java +++ b/plugins/ant/src/com/intellij/lang/ant/dom/AntDomPattern.java @@ -103,7 +103,7 @@ public class AntDomPattern extends AntDomRecursiveVisitor { if (referred != null) { referred.accept(this); } - super.visitDomElement(element); + super.visitAntDomElement(element); } @Nullable diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/application/CvsInfo.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/application/CvsInfo.java index ace6c475de99..d385be061481 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/application/CvsInfo.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/application/CvsInfo.java @@ -27,6 +27,7 @@ import com.intellij.cvsSupport2.errorHandling.ErrorRegistry; import com.intellij.cvsSupport2.javacvsImpl.io.ReadWriteStatistics; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ThreeState; @@ -142,7 +143,7 @@ public class CvsInfo { } private void loadEntries() { - if (myParent != DUMMY_ROOT) { + if (!Comparing.equal(myParent, DUMMY_ROOT)) { myEntries = createEntriesFor(getParentFile()); } else { diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/EclipseClasspathWriter.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/EclipseClasspathWriter.java index 7e7559287839..46887aee7e49 100644 --- a/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/EclipseClasspathWriter.java +++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/EclipseClasspathWriter.java @@ -97,7 +97,7 @@ public class EclipseClasspathWriter { for (SourceFolder sourceFolder : contentEntry.getSourceFolders()) { final String srcUrl = sourceFolder.getUrl(); String relativePath = EPathUtil.collapse2EclipsePath(srcUrl, myModel); - if (contentRoot != EPathUtil.getContentRoot(myModel)) { + if (!Comparing.equal(contentRoot, EPathUtil.getContentRoot(myModel))) { final String linkedPath = EclipseModuleManager.getInstance(entry.getOwnerModule()).getEclipseLinkedSrcVariablePath(srcUrl); if (linkedPath != null) { relativePath = linkedPath; diff --git a/plugins/gettext/src/META-INF/plugin.xml b/plugins/gettext/src/META-INF/plugin.xml index 3f91a8f5968a..79d3d137d04f 100644 --- a/plugins/gettext/src/META-INF/plugin.xml +++ b/plugins/gettext/src/META-INF/plugin.xml @@ -13,20 +13,11 @@ - - - - - - - - - - - - - + + + + \ No newline at end of file diff --git a/plugins/gettext/src/com/jetbrains/gettext/GetText.flex b/plugins/gettext/src/com/jetbrains/gettext/GetText.flex index d20b2d432ec2..da8fea52e09a 100644 --- a/plugins/gettext/src/com/jetbrains/gettext/GetText.flex +++ b/plugins/gettext/src/com/jetbrains/gettext/GetText.flex @@ -26,35 +26,26 @@ import com.jetbrains.gettext.GetTextElementType; %ignorecase EOL = (\r|\n|\r\n) -NO_EOL = !(\r|\n|\r\n) SPACE = [ \t\f] WHITE_SPACE = {EOL} | {SPACE} STRING_TAIL = [^\r\n]* QUOTED_STRING = ("\"")~(\r|\n|\r\n|"\"") -TMP_QUOTED_STRING = ("\"")~("\"") DOUBLEQUOTE = \" -DOUBLEQUOTED_STRING = ([^\"] | \"\" | \\\")+ LBRACE = "[" RBRACE = "]" NUMBER = [0-9]* +LETTERS = [a-zA-Z]* COMMENT_SYMBOL = "#" -COMMENT_TYPE_SYMBOLS = ("#."|"#:"|"#,"|"#|") -COMMENT = (" "|\t|\f)~{EOL} -EXTRACTED_COMMENT = (".")~{EOL} -REFERENCE_COMMENT = (":")~{EOL} -PREVIOUS_COMMENT = ("|")~{EOL} +EXTRACTED_COMMENT = ("."){STRING_TAIL} +REFERENCE_COMMENT = (":"){STRING_TAIL} +PREVIOUS_COMMENT = ("|"){STRING_TAIL} FLAG_GROUP = (",") -DOT = "." -COLON = ":" -LINE = "|" -COMMA = "," - MSGCTXT = "msgctxt" MSGID = "msgid" MSGID_PLURAL = "msgid_plural" @@ -62,43 +53,17 @@ MSGSTR = "msgstr" FUZZY_FLAG = "fuzzy" -NO = "no-" FORMAT = "-format" -C = "c" -OBJC = "objc" -SH = "sh" -PYTHON = "python" -LISP = "lisp" -ELISP = "elisp" -LIBREP = "librep" -SCHEME = "scheme" -SMALLTALK = "smalltalk" -JAVA = "java" -CSHARP = "csharp" -AWK = "awk" -YCP = "ycp" -TCL = "tcl" -PERL = "perl-brace" -PHP = "php" -GCC = "gcc-internal" -GFC = "gfc-internal" -QT = "qt" -KDE = "kde" -BOOST = "boost" -OBJECT_PASCAL = "object-pascal" -QT_PLURAL = "qt-plural" - -PASCAL_FORMAT_FLAG = "object-pascal-format" -NO_PASCAL_FORMAT_FLAG = "no-object-pascal-format" -QT_FORMAT_FLAG = "qt-plural-format" -NO_QT_FORMAT_FLAG = "no-qt-plural-format" -FORMAT_FLAG = (C|OBJC|SH|PYTHON|LISP|EISP|LIBREP|SCHEME|SMALLTALK|JAVA|SCHARP|AWK|OBJECT_PASCAL|YCP|TCL|PERL|PHP|GCC|GFC|QT|QT_PLURAL|KDE|BOOST) {FORMAT} +NO = "no-" +FORMAT_FLAG = ("c"|"objc"|"sh"|"python"|"lisp"|"elisp"|"librep"|"scheme"|"smalltalk"|"java"| +"csharp"|"awk"|"object-pascal"|"ycp"|"tcl"|"perl-brace"|"php"|"gcc-internal"|"gfc-internal"| +"qt"|"qt-plural"|"kde"|"boost") {FORMAT} NO_FORMAT_FLAG = {NO} {FORMAT_FLAG} - RANGE_FLAG = "range" DOTS = ".." FLAG_DELIVERY="," +COLON = ":" %state START_COMMENT %state COMMENT @@ -114,10 +79,10 @@ FLAG_DELIVERY="," {COMMENT_SYMBOL} { yybegin(START_COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS;} {SPACE} { yybegin(COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS;} - {DOT} { yybegin(EXTR_COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS;} - {COLON} { yybegin(REFERENCE_COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS;} - {LINE} { yybegin(PREVIOUS_COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS;} - {FLAG_GROUP} { yybegin(FLAG_COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS;} + {EXTRACTED_COMMENT} { yybegin(EXTR_COMMENT); return GetTextTokenTypes.EXTR_COMMENT;} + {REFERENCE_COMMENT} { yybegin(REFERENCE_COMMENT); return GetTextTokenTypes.REFERENCE;} + {PREVIOUS_COMMENT} { yybegin(PREVIOUS_COMMENT); return GetTextTokenTypes.PREVIOUS_COMMENT;} + {FLAG_GROUP} { yybegin(FLAG_COMMENT); return GetTextTokenTypes.FLAG_COMMENT;} {EOL} { yybegin(YYINITIAL); return GetTextTokenTypes.WHITE_SPACE;} {EOL} { yybegin(YYINITIAL); return GetTextTokenTypes.WHITE_SPACE;} @@ -132,29 +97,31 @@ FLAG_DELIVERY="," {STRING_TAIL} { return GetTextTokenTypes.REFERENCE;} {STRING_TAIL} { return GetTextTokenTypes.PREVIOUS_COMMENT;} - {PASCAL_FORMAT_FLAG} { yybegin(FLAG_DEL); return GetTextTokenTypes.FORMAT_FLAG;} - {NO_PASCAL_FORMAT_FLAG} { yybegin(FLAG_DEL); return GetTextTokenTypes.NO_FORMAT_FLAG;} - {QT_FORMAT_FLAG} { yybegin(FLAG_DEL); return GetTextTokenTypes.FORMAT_FLAG;} - {NO_QT_FORMAT_FLAG} { yybegin(FLAG_DEL); return GetTextTokenTypes.NO_FORMAT_FLAG;} {FORMAT_FLAG} { yybegin(FLAG_DEL); return GetTextTokenTypes.FORMAT_FLAG;} {NO_FORMAT_FLAG} { yybegin(FLAG_DEL); return GetTextTokenTypes.NO_FORMAT_FLAG;} {FUZZY_FLAG} { yybegin(FLAG_DEL); return GetTextTokenTypes.FUZZY_FLAG;} {RANGE_FLAG} { yybegin(FLAG_DEL); return GetTextTokenTypes.RANGE_FLAG;} {FLAG_DELIVERY} { yybegin(FLAG_COMMENT); return GetTextTokenTypes.FLAG_DELIVERY;} + {SPACE} { return GetTextTokenTypes.FLAG_DELIVERY;} + {NUMBER} { return GetTextTokenTypes.RANGE_NUMBER;} + {COLON} { return GetTextTokenTypes.COLON;} + {DOTS} { return GetTextTokenTypes.DOTS;} + [^] { return GetTextTokenTypes.BAD_FLAG_COMMENT; } +{MSGCTXT} { return GetTextTokenTypes.MSGCTXT;} {MSGCTXT} { return GetTextTokenTypes.MSGCTXT;} {MSGID} { return GetTextTokenTypes.MSGID;} {MSGID_PLURAL} { return GetTextTokenTypes.MSGID_PLURAL;} {MSGSTR} { return GetTextTokenTypes.MSGSTR;} + {LETTERS} { return GetTextTokenTypes.COMMAND;} {WHITE_SPACE} { return GetTextTokenTypes.WHITE_SPACE;} - {SPACE} { return GetTextTokenTypes.WHITE_SPACE;} + {NUMBER} { return GetTextTokenTypes.NUMBER;} {LBRACE} { return GetTextTokenTypes.LBRACE;} {RBRACE} { return GetTextTokenTypes.RBRACE;} -{COLON} { return GetTextTokenTypes.COLON;} -{DOTS} { return GetTextTokenTypes.DOTS;} +{DOUBLEQUOTE} { return GetTextTokenTypes.QUOTE;} {QUOTED_STRING} { return GetTextTokenTypes.STRING;} diff --git a/plugins/gettext/src/com/jetbrains/gettext/GetTextFileViewProvider.java b/plugins/gettext/src/com/jetbrains/gettext/GetTextFileViewProvider.java deleted file mode 100644 index 2b806f7e9875..000000000000 --- a/plugins/gettext/src/com/jetbrains/gettext/GetTextFileViewProvider.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.jetbrains.gettext; - -import com.intellij.lang.Language; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiManager; -import com.intellij.psi.SingleRootFileViewProvider; -import org.jetbrains.annotations.NotNull; - -/** - * @author Svetlana.Zemlyanskaya - */ -public class GetTextFileViewProvider extends SingleRootFileViewProvider { - - protected GetTextFileViewProvider(@NotNull PsiManager manager, @NotNull VirtualFile virtualFile, final boolean physical, @NotNull Language language) { - super(manager, virtualFile, physical, language); - } - - public boolean supportsIncrementalReparse(@NotNull final Language rootLanguage) { - return false; - } -} diff --git a/plugins/gettext/src/com/jetbrains/gettext/GetTextFileViewProviderFactory.java b/plugins/gettext/src/com/jetbrains/gettext/GetTextFileViewProviderFactory.java deleted file mode 100644 index 07d5914c3166..000000000000 --- a/plugins/gettext/src/com/jetbrains/gettext/GetTextFileViewProviderFactory.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.jetbrains.gettext; - -import com.intellij.lang.Language; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.FileViewProvider; -import com.intellij.psi.FileViewProviderFactory; -import com.intellij.psi.PsiManager; -import org.jetbrains.annotations.NotNull; - -/** - * @author Svetlana.Zemlyanskaya - */ -public class GetTextFileViewProviderFactory implements FileViewProviderFactory { - - public FileViewProvider createFileViewProvider(@NotNull VirtualFile file, Language language, @NotNull PsiManager manager, boolean physical) { - return new GetTextFileViewProvider(manager, file, physical, language); - } -} diff --git a/plugins/gettext/src/com/jetbrains/gettext/GetTextTokenTypes.java b/plugins/gettext/src/com/jetbrains/gettext/GetTextTokenTypes.java index fb32c5570c45..83f27856073e 100644 --- a/plugins/gettext/src/com/jetbrains/gettext/GetTextTokenTypes.java +++ b/plugins/gettext/src/com/jetbrains/gettext/GetTextTokenTypes.java @@ -24,9 +24,9 @@ public interface GetTextTokenTypes { IElementType FORMAT_FLAG = new GetTextElementType("FORMAT_FLAG"); IElementType NO_FORMAT_FLAG = new GetTextElementType("NO_FORMAT_FLAG"); IElementType FLAG_DELIVERY = new GetTextElementType("DELIVERY"); + IElementType BAD_FLAG_COMMENT = new GetTextElementType("BAD_FLAG_COMMENT"); - IElementType MSG = new GetTextElementType("MSG_START"); - + IElementType COMMAND = new GetTextElementType("COMMAND"); IElementType MSGCTXT = new GetTextElementType("MSGCTXT"); IElementType MSGID = new GetTextElementType("MSGID"); IElementType MSGID_PLURAL = new GetTextElementType("MSGID_PLURAL"); @@ -35,15 +35,20 @@ public interface GetTextTokenTypes { IElementType COLON = new GetTextElementType("COLON"); IElementType DOTS = new GetTextElementType("DOTS"); IElementType NUMBER = new GetTextElementType("NUMBER"); + IElementType RANGE_NUMBER = new GetTextElementType("RANGE_NUMBER"); IElementType LBRACE = new GetTextElementType("LBRACE"); IElementType RBRACE = new GetTextElementType("RBRACE"); + IElementType QUOTE = new GetTextElementType("QUOTE"); IElementType STRING = new GetTextElementType("STRING"); - TokenSet SYSTEM_COMMENTS = TokenSet.create(EXTR_COMMENT, REFERENCE, FLAG_COMMENT, PREVIOUS_COMMENT, FLAG_DELIVERY, COMMENT_SYMBOLS); + TokenSet SYSTEM_COMMENTS = TokenSet.create(EXTR_COMMENT, REFERENCE, FLAG_COMMENT, PREVIOUS_COMMENT, + FLAG_DELIVERY, COMMENT_SYMBOLS, BAD_FLAG_COMMENT); TokenSet COMMENTS = TokenSet.orSet(TokenSet.create(COMMENT), SYSTEM_COMMENTS); - TokenSet STRING_LITERALS = TokenSet.create(STRING); - TokenSet KEYWORDS = TokenSet.create(MSG, MSGCTXT, MSGID, MSGID_PLURAL, MSGSTR); + TokenSet STRING_LITERALS = TokenSet.create(STRING, QUOTE); + TokenSet KEYWORDS = TokenSet.create(MSGCTXT, MSGID, MSGID_PLURAL, MSGSTR, COMMAND); TokenSet FLAGS = TokenSet.create(FUZZY_FLAG, FORMAT_FLAG, NO_FORMAT_FLAG, RANGE_FLAG); + TokenSet FLAG_LINE = TokenSet.orSet(FLAGS, TokenSet.create(FLAG_COMMENT,FLAG_DELIVERY, BAD_FLAG_COMMENT, COLON, DOTS, RANGE_NUMBER)); TokenSet BRACES = TokenSet.create(LBRACE, RBRACE); + TokenSet NUMBERS = TokenSet.create(NUMBER, RANGE_NUMBER); } diff --git a/plugins/gettext/src/com/jetbrains/gettext/_GetTextLexer.java b/plugins/gettext/src/com/jetbrains/gettext/_GetTextLexer.java index 9b20ffd1d9cf..9919e79601f0 100644 --- a/plugins/gettext/src/com/jetbrains/gettext/_GetTextLexer.java +++ b/plugins/gettext/src/com/jetbrains/gettext/_GetTextLexer.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex 1.4.3 on 7/10/12 5:05 PM */ +/* The following code was generated by JFlex 1.4.3 on 7/11/12 4:30 PM */ package com.jetbrains.gettext; @@ -9,7 +9,7 @@ import com.intellij.psi.tree.IElementType; /** * This class is a scanner generated by * JFlex 1.4.3 - * on 7/10/12 5:05 PM from the specification file + * on 7/11/12 4:30 PM from the specification file * /home/svetlana/git/idea/IDEA/tools/lexer/../../community/plugins/gettext/src/com/jetbrains/gettext/GetText.flex */ class _GetTextLexer implements FlexLexer { @@ -41,13 +41,13 @@ class _GetTextLexer implements FlexLexer { */ private static final String ZZ_CMAP_PACKED = "\11\0\1\3\1\2\1\0\1\3\1\1\22\0\1\3\1\0\1\4"+ - "\1\10\10\0\1\13\1\40\1\11\1\0\12\7\1\12\6\0\1\32"+ - "\1\41\1\20\1\24\1\44\1\33\1\17\1\43\1\23\1\42\1\45"+ - "\1\27\1\15\1\36\1\37\1\26\1\50\1\31\1\16\1\21\1\30"+ - "\1\46\1\47\1\22\1\35\1\34\1\5\1\0\1\6\1\0\1\25"+ - "\1\0\1\32\1\41\1\20\1\24\1\44\1\33\1\17\1\43\1\23"+ - "\1\42\1\45\1\27\1\15\1\36\1\37\1\26\1\50\1\31\1\16"+ - "\1\21\1\30\1\46\1\47\1\22\1\35\1\34\1\0\1\14\uff83\0"; + "\1\11\10\0\1\15\1\37\1\12\1\0\12\7\1\13\6\0\1\33"+ + "\1\42\1\21\1\25\1\45\1\34\1\20\1\44\1\24\1\43\1\46"+ + "\1\30\1\16\1\41\1\40\1\27\1\10\1\32\1\17\1\22\1\31"+ + "\1\47\1\50\1\23\1\36\1\35\1\5\1\0\1\6\1\0\1\26"+ + "\1\0\1\33\1\42\1\21\1\25\1\45\1\34\1\20\1\44\1\24"+ + "\1\43\1\46\1\30\1\16\1\41\1\40\1\27\1\10\1\32\1\17"+ + "\1\22\1\31\1\47\1\50\1\23\1\36\1\35\1\0\1\14\uff83\0"; /** * Translates characters to character classes @@ -60,15 +60,18 @@ class _GetTextLexer implements FlexLexer { private static final int [] ZZ_ACTION = zzUnpackAction(); private static final String ZZ_ACTION_PACKED_0 = - "\2\1\1\2\1\3\1\4\1\5\2\1\1\6\2\7"+ - "\1\6\1\10\1\11\1\1\1\12\1\6\1\13\1\6"+ - "\2\14\1\15\1\16\1\17\1\20\1\21\2\2\2\3"+ - "\2\4\2\5\21\6\1\22\1\0\2\23\1\24\101\0"+ - "\1\25\3\0\1\26\1\27\22\0\1\30\20\0\1\31"+ - "\17\0\1\32\23\0\1\33\1\0\1\34\2\0"; + "\1\1\1\2\1\3\1\4\1\5\1\6\2\7\1\10"+ + "\2\11\1\12\1\13\1\14\1\2\1\1\1\15\1\1"+ + "\2\16\1\17\1\20\1\21\1\22\1\23\1\10\2\3"+ + "\2\4\2\5\2\6\1\24\1\25\1\24\1\7\2\24"+ + "\1\26\21\24\1\27\1\0\2\30\1\1\2\0\1\31"+ + "\24\0\1\1\21\0\3\1\36\0\2\1\1\32\2\0"+ + "\1\32\6\0\1\33\1\34\23\0\1\35\1\1\1\0"+ + "\1\35\24\0\1\36\1\0\1\36\23\0\1\37\34\0"+ + "\1\40\2\0\1\41\3\0"; private static int [] zzUnpackAction() { - int [] result = new int[203]; + int [] result = new int[252]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -94,34 +97,40 @@ class _GetTextLexer implements FlexLexer { private static final String ZZ_ROWMAP_PACKED_0 = "\0\0\0\51\0\122\0\173\0\244\0\315\0\366\0\u011f"+ - "\0\u0148\0\u0171\0\u0148\0\u019a\0\u0148\0\u0148\0\u01c3\0\u0148"+ - "\0\u01ec\0\u0148\0\u0215\0\u023e\0\u0148\0\u0148\0\u01ec\0\u0148"+ - "\0\u0148\0\u0148\0\u0267\0\u0290\0\u02b9\0\u02e2\0\u030b\0\u0334"+ - "\0\u035d\0\u0386\0\u03af\0\u03d8\0\u0401\0\u042a\0\u0453\0\u047c"+ - "\0\u04a5\0\u04ce\0\u04f7\0\u0520\0\u0549\0\u0572\0\u059b\0\u05c4"+ - "\0\u05ed\0\u0616\0\u063f\0\u0148\0\u019a\0\u0668\0\u0148\0\u0148"+ - "\0\u0691\0\u06ba\0\u06e3\0\u0401\0\u070c\0\u0735\0\u075e\0\u0787"+ - "\0\u07b0\0\u07d9\0\u0802\0\u082b\0\u0854\0\u087d\0\u08a6\0\u08cf"+ + "\0\u0148\0\u0171\0\u0148\0\u019a\0\u0148\0\u0148\0\u01c3\0\u01ec"+ + "\0\u0148\0\u0215\0\u023e\0\u0148\0\u0148\0\u0267\0\u0290\0\u02b9"+ + "\0\u0148\0\u02e2\0\u030b\0\u0334\0\u035d\0\u0386\0\u03af\0\u03d8"+ + "\0\u0401\0\u042a\0\u0148\0\u0148\0\u019a\0\u0453\0\u047c\0\u04a5"+ + "\0\u0148\0\u02e2\0\u04ce\0\u04f7\0\u0520\0\u0549\0\u0572\0\u059b"+ + "\0\u05c4\0\u05ed\0\u0616\0\u063f\0\u0668\0\u0691\0\u06ba\0\u06e3"+ + "\0\u070c\0\u0735\0\u0148\0\u019a\0\u075e\0\u0148\0\u0787\0\u07b0"+ + "\0\u07d9\0\u0148\0\u0802\0\u082b\0\u0854\0\u087d\0\u08a6\0\u08cf"+ "\0\u08f8\0\u0921\0\u094a\0\u0973\0\u099c\0\u09c5\0\u09ee\0\u0a17"+ "\0\u0a40\0\u0a69\0\u0a92\0\u0abb\0\u0ae4\0\u0b0d\0\u0b36\0\u0b5f"+ "\0\u0b88\0\u0bb1\0\u0bda\0\u0c03\0\u0c2c\0\u0c55\0\u0c7e\0\u0ca7"+ "\0\u0cd0\0\u0cf9\0\u0d22\0\u0d4b\0\u0d74\0\u0d9d\0\u0dc6\0\u0def"+ "\0\u0e18\0\u0e41\0\u0e6a\0\u0e93\0\u0ebc\0\u0ee5\0\u0f0e\0\u0f37"+ "\0\u0f60\0\u0f89\0\u0fb2\0\u0fdb\0\u1004\0\u102d\0\u1056\0\u107f"+ - "\0\u10a8\0\u10d1\0\u10fa\0\u1123\0\u114c\0\u0148\0\u0148\0\u1175"+ - "\0\u119e\0\u11c7\0\u11f0\0\u1219\0\u1242\0\u126b\0\u1294\0\u12bd"+ - "\0\u12e6\0\u130f\0\u1338\0\u1361\0\u138a\0\u13b3\0\u13dc\0\u1405"+ - "\0\u142e\0\u0148\0\u1457\0\u1480\0\u14a9\0\u14d2\0\u14fb\0\u1524"+ - "\0\u154d\0\u1576\0\u159f\0\u15c8\0\u15f1\0\u161a\0\u1643\0\u166c"+ - "\0\u1695\0\u16be\0\u0148\0\u16e7\0\u1710\0\u1739\0\u1762\0\u178b"+ - "\0\u17b4\0\u17dd\0\u1806\0\u182f\0\u1858\0\u1881\0\u18aa\0\u18d3"+ - "\0\u18fc\0\u1925\0\u0148\0\u194e\0\u1977\0\u19a0\0\u19c9\0\u19f2"+ - "\0\u1a1b\0\u1a44\0\u1a6d\0\u1a96\0\u1abf\0\u1ae8\0\u1b11\0\u1b3a"+ - "\0\u1b63\0\u1b8c\0\u1bb5\0\u1bde\0\u1c07\0\u1c30\0\u0148\0\u1c59"+ - "\0\u0148\0\u1c82\0\u1cab"; + "\0\u10a8\0\u10d1\0\u10fa\0\u1123\0\u114c\0\u1175\0\u119e\0\u11c7"+ + "\0\u11f0\0\u1219\0\u1242\0\u126b\0\u1294\0\u12bd\0\u12e6\0\u130f"+ + "\0\u1338\0\u1361\0\u138a\0\u13b3\0\u13dc\0\u1405\0\u142e\0\u1457"+ + "\0\u1480\0\u14a9\0\u14d2\0\u14fb\0\u1524\0\u0148\0\u0148\0\u154d"+ + "\0\u1576\0\u159f\0\u15c8\0\u15f1\0\u161a\0\u1643\0\u166c\0\u1695"+ + "\0\u16be\0\u16e7\0\u1710\0\u1739\0\u1762\0\u178b\0\u17b4\0\u17dd"+ + "\0\u1806\0\u182f\0\u01ec\0\u1858\0\u1881\0\u0148\0\u18aa\0\u18d3"+ + "\0\u18fc\0\u1925\0\u194e\0\u1977\0\u19a0\0\u19c9\0\u19f2\0\u1a1b"+ + "\0\u1a44\0\u1a6d\0\u1a96\0\u1abf\0\u1ae8\0\u1b11\0\u1b3a\0\u1b63"+ + "\0\u1b8c\0\u1bb5\0\u01ec\0\u1bde\0\u0148\0\u1c07\0\u1c30\0\u1c59"+ + "\0\u1c82\0\u1cab\0\u1cd4\0\u1cfd\0\u1d26\0\u1d4f\0\u1d78\0\u1da1"+ + "\0\u1dca\0\u1df3\0\u1e1c\0\u1e45\0\u1e6e\0\u1e97\0\u1ec0\0\u1ee9"+ + "\0\u0148\0\u1f12\0\u1f3b\0\u1f64\0\u1f8d\0\u1fb6\0\u1fdf\0\u2008"+ + "\0\u2031\0\u205a\0\u2083\0\u20ac\0\u20d5\0\u20fe\0\u2127\0\u2150"+ + "\0\u2179\0\u21a2\0\u21cb\0\u21f4\0\u221d\0\u2246\0\u226f\0\u2298"+ + "\0\u22c1\0\u22ea\0\u2313\0\u233c\0\u2365\0\u0148\0\u238e\0\u23b7"+ + "\0\u0148\0\u23e0\0\u2409\0\u2432"; private static int [] zzUnpackRowMap() { - int [] result = new int[203]; + int [] result = new int[252]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -145,76 +154,98 @@ class _GetTextLexer implements FlexLexer { private static final String ZZ_TRANS_PACKED_0 = "\1\11\1\12\2\13\1\14\1\15\1\16\1\17\1\20"+ - "\1\21\1\22\2\11\1\23\34\11\1\24\1\25\1\26"+ - "\1\14\1\15\1\16\1\17\1\11\1\27\1\30\1\31"+ - "\1\32\1\23\33\11\1\33\1\24\1\25\1\33\1\34"+ - "\44\33\1\35\1\24\1\25\1\35\1\36\44\35\1\37"+ - "\1\24\1\25\1\37\1\40\44\37\1\41\1\24\1\25"+ - "\1\41\1\42\44\41\1\11\1\24\1\25\1\13\1\14"+ - "\1\15\1\16\1\17\1\11\1\21\1\22\2\11\1\23"+ - "\1\43\1\44\1\45\1\46\4\11\1\47\1\50\1\11"+ - "\1\51\1\52\1\53\1\11\1\54\1\55\1\56\1\11"+ - "\1\57\1\60\1\11\1\61\1\62\2\11\1\63\1\11"+ - "\1\24\1\25\1\13\1\14\1\15\1\16\1\17\1\11"+ - "\1\21\1\22\1\64\1\11\1\23\33\11\53\0\1\13"+ - "\46\0\1\65\1\66\1\67\1\65\1\67\44\65\7\0"+ - "\1\17\52\0\1\70\55\0\1\71\34\0\1\25\46\0"+ - "\1\33\2\0\46\33\1\34\1\66\1\67\1\34\1\33"+ - "\44\34\1\35\2\0\46\35\1\36\1\66\1\67\1\36"+ - "\1\35\44\36\1\37\2\0\46\37\1\40\1\66\1\67"+ - "\1\40\1\37\44\40\1\41\2\0\46\41\1\42\1\66"+ - "\1\67\1\42\1\41\44\42\15\0\1\72\2\0\1\73"+ - "\22\0\1\74\25\0\1\75\12\0\1\75\55\0\1\76"+ - "\30\0\1\77\65\0\1\100\5\0\1\101\1\102\27\0"+ - "\1\103\57\0\1\104\65\0\1\105\31\0\1\106\40\0"+ - "\1\101\67\0\1\107\52\0\1\110\46\0\1\111\43\0"+ - "\1\112\41\0\1\113\51\0\1\114\45\0\1\115\31\0"+ - "\1\67\65\0\1\116\63\0\1\117\61\0\1\120\25\0"+ - "\1\74\63\0\1\121\44\0\1\74\42\0\1\122\55\0"+ - "\1\74\53\0\1\77\35\0\1\101\22\0\1\123\45\0"+ - "\1\124\57\0\1\74\37\0\1\125\54\0\1\126\52\0"+ - "\1\127\45\0\1\130\57\0\1\131\20\0\1\101\76\0"+ - "\1\74\31\0\1\132\12\0\1\133\26\0\1\134\1\0"+ - "\1\135\2\0\1\136\54\0\1\137\53\0\1\140\11\0"+ - "\1\141\43\0\1\142\54\0\1\143\36\0\1\144\36\0"+ - "\1\145\65\0\1\146\32\0\1\147\1\150\1\151\1\152"+ - "\4\0\1\153\1\154\2\0\1\155\2\0\1\156\1\0"+ - "\1\157\1\0\1\160\1\161\1\0\1\162\1\163\2\0"+ - "\1\164\20\0\1\74\23\0\1\165\22\0\1\166\64\0"+ - "\1\74\44\0\1\167\50\0\1\167\4\0\1\121\36\0"+ - "\1\170\50\0\1\171\53\0\1\172\53\0\1\173\52\0"+ - "\1\101\34\0\1\114\64\0\1\174\56\0\1\175\55\0"+ - "\1\101\50\0\1\176\41\0\1\177\30\0\1\200\2\0"+ - "\1\201\22\0\1\151\25\0\1\202\12\0\1\202\55\0"+ - "\1\203\30\0\1\204\65\0\1\205\5\0\1\206\1\207"+ - "\27\0\1\210\74\0\1\211\21\0\1\206\71\0\1\212"+ - "\46\0\1\213\43\0\1\214\41\0\1\215\51\0\1\216"+ - "\45\0\1\217\47\0\1\220\51\0\1\74\56\0\1\221"+ - "\52\0\1\222\41\0\1\223\53\0\1\224\44\0\1\225"+ - "\44\0\1\226\71\0\1\74\44\0\1\227\61\0\1\230"+ - "\25\0\1\151\63\0\1\231\44\0\1\151\42\0\1\232"+ - "\55\0\1\151\53\0\1\204\35\0\1\206\22\0\1\233"+ - "\54\0\1\151\45\0\1\234\45\0\1\235\57\0\1\236"+ - "\20\0\1\206\76\0\1\151\31\0\1\237\12\0\1\240"+ - "\31\0\1\241\57\0\1\242\41\0\1\243\55\0\1\244"+ - "\54\0\1\245\50\0\1\246\45\0\1\247\53\0\1\250"+ - "\11\0\1\251\43\0\1\252\54\0\1\253\36\0\1\254"+ - "\37\0\1\151\23\0\1\255\22\0\1\256\64\0\1\151"+ - "\44\0\1\257\50\0\1\257\4\0\1\231\42\0\1\260"+ - "\12\0\1\260\41\0\1\261\46\0\1\262\50\0\1\105"+ - "\42\0\1\263\56\0\1\264\52\0\1\206\34\0\1\216"+ - "\64\0\1\265\56\0\1\266\55\0\1\206\24\0\1\267"+ - "\51\0\1\151\56\0\1\270\47\0\1\271\54\0\1\77"+ - "\46\0\1\272\41\0\1\273\44\0\1\274\71\0\1\151"+ - "\33\0\1\275\57\0\1\276\52\0\1\277\47\0\1\300"+ - "\51\0\1\301\50\0\1\302\43\0\1\303\12\0\1\303"+ - "\41\0\1\304\35\0\1\305\64\0\1\306\45\0\1\211"+ - "\42\0\1\307\55\0\1\310\54\0\1\204\36\0\1\261"+ - "\57\0\1\311\53\0\1\312\34\0\1\313\52\0\1\304"+ - "\30\0"; + "\1\21\4\11\1\22\7\20\1\11\10\20\1\11\11\20"+ + "\1\11\1\23\1\24\1\25\1\14\1\15\1\16\1\17"+ + "\2\11\1\26\1\27\1\30\1\31\1\32\32\11\1\33"+ + "\1\23\1\24\1\33\1\34\44\33\1\35\1\23\1\24"+ + "\1\35\1\36\44\35\1\37\1\23\1\24\1\37\1\40"+ + "\44\37\1\41\1\23\1\24\1\41\1\42\44\41\1\43"+ + "\1\23\1\24\1\44\1\45\2\43\1\46\1\47\1\43"+ + "\1\50\1\51\2\43\1\52\1\53\1\54\1\55\1\56"+ + "\4\43\1\57\1\60\1\43\1\61\1\62\1\63\1\43"+ + "\1\64\1\43\1\65\1\66\1\67\1\70\1\43\1\71"+ + "\1\72\3\43\1\23\1\24\1\44\1\45\2\43\1\46"+ + "\2\43\1\50\1\51\1\43\1\73\1\52\32\43\53\0"+ + "\1\13\46\0\1\74\1\75\1\76\1\74\1\76\44\74"+ + "\7\0\1\17\51\0\1\20\5\0\10\20\1\0\10\20"+ + "\1\0\11\20\10\0\1\20\5\0\1\20\1\77\6\20"+ + "\1\0\10\20\1\0\11\20\2\0\1\24\46\0\1\26"+ + "\2\0\46\26\1\27\2\0\46\27\1\30\2\0\46\30"+ + "\17\0\1\100\31\0\1\33\2\0\46\33\1\34\1\75"+ + "\1\76\1\34\1\33\44\34\1\35\2\0\46\35\1\36"+ + "\1\75\1\76\1\36\1\35\44\36\1\37\2\0\46\37"+ + "\1\40\1\75\1\76\1\40\1\37\44\40\1\41\2\0"+ + "\46\41\1\42\1\75\1\76\1\42\1\41\44\42\7\0"+ + "\1\46\63\0\1\101\40\0\1\102\54\0\1\103\2\0"+ + "\1\104\22\0\1\105\25\0\1\106\12\0\1\106\33\0"+ + "\1\107\17\0\1\110\32\0\1\111\65\0\1\112\5\0"+ + "\1\113\1\114\27\0\1\115\57\0\1\116\65\0\1\117"+ + "\31\0\1\120\40\0\1\113\71\0\1\121\46\0\1\122"+ + "\50\0\1\123\43\0\1\124\45\0\1\125\45\0\1\126"+ + "\25\0\1\76\56\0\1\20\5\0\2\20\1\127\5\20"+ + "\1\0\10\20\1\0\11\20\20\0\1\130\67\0\1\131"+ + "\44\0\1\132\61\0\1\133\43\0\1\110\32\0\1\134"+ + "\73\0\1\135\40\0\1\136\44\0\1\105\42\0\1\137"+ + "\55\0\1\105\53\0\1\140\35\0\1\113\22\0\1\141"+ + "\47\0\1\142\55\0\1\105\37\0\1\143\56\0\1\144"+ + "\44\0\1\145\51\0\1\146\57\0\1\147\25\0\1\150"+ + "\71\0\1\105\13\0\1\20\5\0\1\20\1\151\1\20"+ + "\1\152\2\20\1\153\1\20\1\0\10\20\1\0\11\20"+ + "\17\0\1\154\1\0\1\155\2\0\1\156\53\0\1\157"+ + "\4\0\1\136\44\0\1\160\65\0\1\161\42\0\1\162"+ + "\44\0\1\163\55\0\1\164\54\0\1\165\34\0\1\166"+ + "\52\0\1\167\36\0\1\170\65\0\1\171\34\0\1\105"+ + "\23\0\1\172\13\0\1\173\6\0\1\174\1\175\1\176"+ + "\1\177\4\0\1\200\1\201\2\0\1\202\2\0\1\203"+ + "\1\0\1\204\1\0\1\205\1\206\1\0\1\207\1\210"+ + "\21\0\1\211\64\0\1\105\34\0\1\113\41\0\1\20"+ + "\5\0\4\20\1\212\3\20\1\0\10\20\1\0\11\20"+ + "\10\0\1\20\5\0\4\20\1\213\3\20\1\0\10\20"+ + "\1\0\11\20\10\0\1\20\5\0\7\20\1\214\1\0"+ + "\10\20\1\0\11\20\22\0\1\215\50\0\1\216\53\0"+ + "\1\217\53\0\1\220\50\0\1\221\36\0\1\126\56\0"+ + "\1\222\56\0\1\113\50\0\1\223\56\0\1\224\47\0"+ + "\1\225\56\0\1\113\50\0\1\226\41\0\1\227\33\0"+ + "\1\230\51\0\1\231\44\0\1\232\2\0\1\233\22\0"+ + "\1\234\25\0\1\235\12\0\1\235\33\0\1\236\17\0"+ + "\1\237\32\0\1\240\65\0\1\241\5\0\1\242\1\243"+ + "\27\0\1\244\74\0\1\245\21\0\1\242\71\0\1\246"+ + "\46\0\1\247\43\0\1\250\45\0\1\251\45\0\1\252"+ + "\45\0\1\105\36\0\1\20\5\0\10\20\1\0\3\20"+ + "\1\253\4\20\1\0\11\20\10\0\1\20\5\0\5\20"+ + "\1\254\2\20\1\0\10\20\1\0\11\20\10\0\1\20"+ + "\5\0\10\20\1\255\10\20\1\0\11\20\32\0\1\256"+ + "\41\0\1\257\53\0\1\255\53\0\1\260\41\0\1\261"+ + "\67\0\1\262\25\0\1\263\73\0\1\105\51\0\1\264"+ + "\30\0\1\265\65\0\1\266\44\0\1\267\61\0\1\270"+ + "\43\0\1\237\32\0\1\271\73\0\1\272\40\0\1\273"+ + "\44\0\1\234\42\0\1\274\55\0\1\234\53\0\1\275"+ + "\35\0\1\242\22\0\1\276\54\0\1\234\45\0\1\277"+ + "\45\0\1\300\57\0\1\301\25\0\1\302\71\0\1\234"+ + "\13\0\1\20\5\0\4\20\1\303\3\20\1\0\10\20"+ + "\1\0\11\20\27\0\1\304\43\0\1\305\60\0\1\306"+ + "\51\0\1\307\37\0\1\310\61\0\1\311\47\0\1\312"+ + "\55\0\1\313\40\0\1\314\4\0\1\273\44\0\1\315"+ + "\65\0\1\316\42\0\1\317\44\0\1\320\55\0\1\321"+ + "\54\0\1\322\34\0\1\323\52\0\1\324\37\0\1\234"+ + "\23\0\1\325\22\0\1\326\64\0\1\234\34\0\1\242"+ + "\61\0\1\327\53\0\1\111\45\0\1\117\65\0\1\330"+ + "\25\0\1\331\61\0\1\332\44\0\1\333\51\0\1\334"+ + "\50\0\1\335\36\0\1\252\56\0\1\336\56\0\1\242"+ + "\50\0\1\337\56\0\1\340\47\0\1\341\56\0\1\242"+ + "\24\0\1\342\51\0\1\234\57\0\1\343\51\0\1\344"+ + "\37\0\1\126\62\0\1\345\46\0\1\346\41\0\1\347"+ + "\67\0\1\350\25\0\1\351\73\0\1\234\51\0\1\352"+ + "\30\0\1\353\60\0\1\354\57\0\1\306\26\0\1\355"+ + "\63\0\1\356\51\0\1\357\37\0\1\360\61\0\1\361"+ + "\47\0\1\362\55\0\1\363\44\0\1\364\36\0\1\306"+ + "\62\0\1\240\45\0\1\245\65\0\1\365\25\0\1\366"+ + "\61\0\1\367\44\0\1\370\51\0\1\371\52\0\1\372"+ + "\37\0\1\252\62\0\1\373\56\0\1\356\26\0\1\374"+ + "\52\0\1\356\27\0"; private static int [] zzUnpackTrans() { - int [] result = new int[7380]; + int [] result = new int[9307]; int offset = 0; offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); return result; @@ -255,14 +286,16 @@ class _GetTextLexer implements FlexLexer { private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); private static final String ZZ_ATTRIBUTE_PACKED_0 = - "\10\1\1\11\1\1\1\11\1\1\2\11\1\1\1\11"+ - "\1\1\1\11\2\1\2\11\1\1\3\11\31\1\1\11"+ - "\1\0\1\1\2\11\101\0\1\1\3\0\2\11\22\0"+ - "\1\11\20\0\1\11\17\0\1\11\23\0\1\11\1\0"+ - "\1\11\2\0"; + "\10\1\1\11\1\1\1\11\1\1\2\11\2\1\1\11"+ + "\2\1\2\11\3\1\1\11\11\1\2\11\4\1\1\11"+ + "\21\1\1\11\1\0\1\1\1\11\1\1\2\0\1\11"+ + "\24\0\1\1\21\0\3\1\36\0\3\1\2\0\1\1"+ + "\6\0\2\11\23\0\2\1\1\0\1\11\24\0\1\1"+ + "\1\0\1\11\23\0\1\11\34\0\1\11\2\0\1\11"+ + "\3\0"; private static int [] zzUnpackAttribute() { - int [] result = new int[203]; + int [] result = new int[252]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; @@ -574,118 +607,138 @@ class _GetTextLexer implements FlexLexer { zzMarkedPos = zzMarkedPosL; switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { - case 2: + case 3: { return GetTextTokenTypes.COMMENT; } - case 29: break; - case 27: + case 34: break; + case 32: { yybegin(FLAG_DEL); return GetTextTokenTypes.NO_FORMAT_FLAG; } - case 30: break; - case 25: + case 35: break; + case 30: { return GetTextTokenTypes.MSGCTXT; } - case 31: break; - case 14: - { yybegin(EXTR_COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS; - } - case 32: break; - case 7: - { return GetTextTokenTypes.WHITE_SPACE; - } - case 33: break; - case 8: - { return GetTextTokenTypes.LBRACE; - } - case 34: break; - case 10: - { yybegin(START_COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS; - } - case 35: break; - case 26: - { yybegin(FLAG_DEL); return GetTextTokenTypes.FORMAT_FLAG; - } case 36: break; - case 6: - { return GetTextTokenTypes.BAD_CHARACTER; + case 10: + { return GetTextTokenTypes.QUOTE; } case 37: break; case 9: - { return GetTextTokenTypes.RBRACE; + { return GetTextTokenTypes.WHITE_SPACE; } case 38: break; - case 12: - { yybegin(YYINITIAL); return GetTextTokenTypes.WHITE_SPACE; + case 11: + { return GetTextTokenTypes.LBRACE; } case 39: break; - case 16: - { yybegin(FLAG_COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS; + case 18: + { yybegin(PREVIOUS_COMMENT); return GetTextTokenTypes.PREVIOUS_COMMENT; } case 40: break; - case 17: - { yybegin(PREVIOUS_COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS; + case 13: + { yybegin(START_COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS; } case 41: break; - case 20: - { return GetTextTokenTypes.DOTS; + case 31: + { yybegin(FLAG_DEL); return GetTextTokenTypes.FORMAT_FLAG; } case 42: break; - case 4: - { return GetTextTokenTypes.REFERENCE; + case 8: + { return GetTextTokenTypes.BAD_CHARACTER; } case 43: break; - case 24: - { return GetTextTokenTypes.MSGSTR; + case 21: + { return GetTextTokenTypes.FLAG_DELIVERY; } case 44: break; - case 19: - { return GetTextTokenTypes.STRING; + case 12: + { return GetTextTokenTypes.RBRACE; } case 45: break; - case 15: - { yybegin(REFERENCE_COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS; + case 14: + { yybegin(YYINITIAL); return GetTextTokenTypes.WHITE_SPACE; } case 46: break; - case 22: - { yybegin(FLAG_DEL); return GetTextTokenTypes.RANGE_FLAG; + case 25: + { return GetTextTokenTypes.DOTS; } case 47: break; - case 11: - { return GetTextTokenTypes.COLON; + case 5: + { return GetTextTokenTypes.REFERENCE; } case 48: break; - case 1: - { return GetTextTokenTypes.NUMBER; + case 29: + { return GetTextTokenTypes.MSGSTR; } case 49: break; - case 18: - { yybegin(FLAG_COMMENT); return GetTextTokenTypes.FLAG_DELIVERY; + case 24: + { return GetTextTokenTypes.STRING; } case 50: break; - case 3: - { return GetTextTokenTypes.EXTR_COMMENT; + case 7: + { return GetTextTokenTypes.RANGE_NUMBER; } case 51: break; - case 21: - { return GetTextTokenTypes.MSGID; + case 27: + { yybegin(FLAG_DEL); return GetTextTokenTypes.RANGE_FLAG; } case 52: break; - case 5: - { return GetTextTokenTypes.PREVIOUS_COMMENT; + case 22: + { return GetTextTokenTypes.COLON; } case 53: break; - case 28: - { return GetTextTokenTypes.MSGID_PLURAL; + case 2: + { return GetTextTokenTypes.NUMBER; } case 54: break; - case 23: - { yybegin(FLAG_DEL); return GetTextTokenTypes.FUZZY_FLAG; + case 20: + { return GetTextTokenTypes.BAD_FLAG_COMMENT; } case 55: break; - case 13: - { yybegin(COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS; + case 23: + { yybegin(FLAG_COMMENT); return GetTextTokenTypes.FLAG_DELIVERY; } case 56: break; + case 4: + { return GetTextTokenTypes.EXTR_COMMENT; + } + case 57: break; + case 26: + { return GetTextTokenTypes.MSGID; + } + case 58: break; + case 17: + { yybegin(REFERENCE_COMMENT); return GetTextTokenTypes.REFERENCE; + } + case 59: break; + case 6: + { return GetTextTokenTypes.PREVIOUS_COMMENT; + } + case 60: break; + case 19: + { yybegin(FLAG_COMMENT); return GetTextTokenTypes.FLAG_COMMENT; + } + case 61: break; + case 33: + { return GetTextTokenTypes.MSGID_PLURAL; + } + case 62: break; + case 28: + { yybegin(FLAG_DEL); return GetTextTokenTypes.FUZZY_FLAG; + } + case 63: break; + case 15: + { yybegin(COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS; + } + case 64: break; + case 1: + { return GetTextTokenTypes.COMMAND; + } + case 65: break; + case 16: + { yybegin(EXTR_COMMENT); return GetTextTokenTypes.EXTR_COMMENT; + } + case 66: break; default: if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { zzAtEOF = true; diff --git a/plugins/gettext/src/com/jetbrains/gettext/completion/GetTextBraceMatcher.java b/plugins/gettext/src/com/jetbrains/gettext/completion/GetTextBraceMatcher.java new file mode 100644 index 000000000000..825b89ed451c --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/completion/GetTextBraceMatcher.java @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jetbrains.gettext.completion; + +import com.intellij.lang.BracePair; +import com.intellij.lang.PairedBraceMatcher; +import com.intellij.psi.PsiFile; +import com.intellij.psi.tree.IElementType; +import com.jetbrains.gettext.GetTextTokenTypes; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextBraceMatcher implements PairedBraceMatcher { + private static final BracePair[] PAIRS = new BracePair[]{ + new BracePair(GetTextTokenTypes.LBRACE, GetTextTokenTypes.RBRACE, false) + }; + + public BracePair[] getPairs() { + return PAIRS; + } + + public boolean isPairedBracesAllowedBeforeType(@NotNull final IElementType lbraceType, @Nullable final IElementType tokenType) { + return true; + } + + public int getCodeConstructStart(final PsiFile file, int openingBraceOffset) { + return openingBraceOffset; + } +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/completion/GetTextCommenter.java b/plugins/gettext/src/com/jetbrains/gettext/completion/GetTextCommenter.java new file mode 100644 index 000000000000..d868db1802fd --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/completion/GetTextCommenter.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jetbrains.gettext.completion; + +import com.intellij.lang.Commenter; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextCommenter implements Commenter { + public String getLineCommentPrefix() { + return "# "; + } + + public String getBlockCommentPrefix() { + return null; + } + + public String getBlockCommentSuffix() { + return null; + } + + public String getCommentedBlockCommentPrefix() { + return null; + } + + public String getCommentedBlockCommentSuffix() { + return null; + } +} + diff --git a/plugins/gettext/src/com/jetbrains/gettext/completion/GetTextCompletitionContributor.java b/plugins/gettext/src/com/jetbrains/gettext/completion/GetTextCompletionContributor.java similarity index 56% rename from plugins/gettext/src/com/jetbrains/gettext/completion/GetTextCompletitionContributor.java rename to plugins/gettext/src/com/jetbrains/gettext/completion/GetTextCompletionContributor.java index de526dcbcb9b..209585726943 100644 --- a/plugins/gettext/src/com/jetbrains/gettext/completion/GetTextCompletitionContributor.java +++ b/plugins/gettext/src/com/jetbrains/gettext/completion/GetTextCompletionContributor.java @@ -3,9 +3,11 @@ package com.jetbrains.gettext.completion; import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiWhiteSpace; import com.intellij.util.ProcessingContext; import com.jetbrains.gettext.GetTextLanguage; import com.jetbrains.gettext.GetTextTokenTypes; +import com.jetbrains.gettext.lang.GetTextFlags; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -16,52 +18,28 @@ import static com.intellij.patterns.PlatformPatterns.psiElement; /** * @author Svetlana.Zemlyanskaya */ -public class GetTextCompletitionContributor extends CompletionContributor { +public class GetTextCompletionContributor extends CompletionContributor { private final static String[] KEYWORDS = { "msgid", "msgstr", "msgctxt", - "msgid_plural", - "fuzzy", - "c-format" + "msgid_plural" }; - //private final static String[] BUILT_IN_FILTERS = { - // "date", - // "format", - // "replace", - // "url_encode", - // "json_encode", - // "title", - // "capitalize", - // "upper", - // "lower", - // "striptags", - // "join", - // "reverse", - // "length", - // "sort", - // "default", - // "keys", - // "escape", - // "raw", - // "merge" - //}; - private final static List KEYWORD_LOOKUPS = new ArrayList(); - //private final static List BUILT_IN_FILTER_LOOKUPS = new ArrayList(); + private final static List FLAGS_LOOKUPS = new ArrayList(); static { for (String keyword : KEYWORDS) { KEYWORD_LOOKUPS.add(LookupElementBuilder.create(keyword)); } - //for (String filter : BUILT_IN_FILTERS) { - // BUILT_IN_FILTER_LOOKUPS.add(LookupElementBuilder.create(filter)); - //} + for (String flag : GetTextFlags.getAlFlags()) { + FLAGS_LOOKUPS.add(LookupElementBuilder.create(flag)); + } } - public GetTextCompletitionContributor() { + public GetTextCompletionContributor() { extend(CompletionType.BASIC, psiElement().withParent(psiElement().withLanguage(GetTextLanguage.INSTANCE)), new GetTextKeywordCompletionContributor()); } @@ -73,17 +51,18 @@ public class GetTextCompletitionContributor extends CompletionContributor { ProcessingContext context, @NotNull CompletionResultSet result) { final PsiElement currElement = parameters.getPosition().getOriginalElement(); - if (currElement.getNode().getElementType() == GetTextTokenTypes.BAD_CHARACTER) { + PsiElement prevElement = currElement.getPrevSibling(); + + if (currElement.getNode().getElementType() == GetTextTokenTypes.COMMAND || prevElement instanceof PsiWhiteSpace) { for (LookupElementBuilder builder : KEYWORD_LOOKUPS) result.addElement(builder); result.stopHere(); - //return; + return; + } + + if (prevElement != null && GetTextTokenTypes.FLAG_LINE.contains(prevElement.getNode().getElementType())) { + for (LookupElementBuilder builder : FLAGS_LOOKUPS) result.addElement(builder); + result.stopHere(); } - //PsiElement prevElement = currElement.getPrevSibling(); - //if (prevElement != null && prevElement instanceof PsiWhiteSpace) prevElement = prevElement.getPrevSibling(); - //if (prevElement != null && prevElement.getNode().getElementType() == TwigTokenTypes.FILTER) { - // for (LookupElementBuilder builder : BUILT_IN_FILTER_LOOKUPS) result.addElement(builder); - // result.stopHere(); - //} } } } diff --git a/plugins/gettext/src/com/jetbrains/gettext/completion/GetTextQuoteHandler.java b/plugins/gettext/src/com/jetbrains/gettext/completion/GetTextQuoteHandler.java new file mode 100644 index 000000000000..32bf2dbbb58e --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/completion/GetTextQuoteHandler.java @@ -0,0 +1,28 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jetbrains.gettext.completion; + +import com.intellij.codeInsight.editorActions.SimpleTokenSetQuoteHandler; +import com.jetbrains.gettext.GetTextTokenTypes; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextQuoteHandler extends SimpleTokenSetQuoteHandler { + public GetTextQuoteHandler() { + super(GetTextTokenTypes.QUOTE); + } +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/highlighter/GetTextHighlighterData.java b/plugins/gettext/src/com/jetbrains/gettext/highlighter/GetTextHighlighterData.java index cb4f88504791..7e0e12d6923e 100644 --- a/plugins/gettext/src/com/jetbrains/gettext/highlighter/GetTextHighlighterData.java +++ b/plugins/gettext/src/com/jetbrains/gettext/highlighter/GetTextHighlighterData.java @@ -1,6 +1,5 @@ package com.jetbrains.gettext.highlighter; -import com.intellij.openapi.editor.HighlighterColors; import com.intellij.openapi.editor.SyntaxHighlighterColors; import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.editor.colors.TextAttributesKeyDefaults; @@ -12,40 +11,29 @@ public class GetTextHighlighterData { public static final String COMMENT_ID = "GET_TEXT_COMMENT"; public static final TextAttributesKey COMMENT = - TextAttributesKeyDefaults.createTextAttributesKey(COMMENT_ID, TextAttributesKeyDefaults - .getDefaultAttributes(SyntaxHighlighterColors.LINE_COMMENT).clone()); + TextAttributesKeyDefaults.createTextAttributesKey(COMMENT_ID, TextAttributesKeyDefaults.getDefaultAttributes(SyntaxHighlighterColors.LINE_COMMENT).clone()); public static final String KEYWORD_ID = "GET_TEXT_KEYWORD"; public static final TextAttributesKey KEYWORD = - TextAttributesKeyDefaults - .createTextAttributesKey(KEYWORD_ID, TextAttributesKeyDefaults.getDefaultAttributes(SyntaxHighlighterColors.KEYWORD).clone()); + TextAttributesKeyDefaults.createTextAttributesKey(KEYWORD_ID, TextAttributesKeyDefaults.getDefaultAttributes(SyntaxHighlighterColors.KEYWORD).clone()); public static final String STRING_ID = "GET_TEXT_STRING"; public static final TextAttributesKey STRING = - TextAttributesKeyDefaults - .createTextAttributesKey(STRING_ID, TextAttributesKeyDefaults.getDefaultAttributes(SyntaxHighlighterColors.STRING).clone()); + TextAttributesKeyDefaults.createTextAttributesKey(STRING_ID, TextAttributesKeyDefaults.getDefaultAttributes(SyntaxHighlighterColors.STRING).clone()); public static final String FLAG_ID = "GET_TEXT_FLAG"; public static final TextAttributesKey FLAG = - TextAttributesKeyDefaults.createTextAttributesKey(FLAG_ID, TextAttributesKeyDefaults - .getDefaultAttributes(SyntaxHighlighterColors.DOC_COMMENT_TAG).clone()); + TextAttributesKeyDefaults.createTextAttributesKey(FLAG_ID, TextAttributesKeyDefaults.getDefaultAttributes(SyntaxHighlighterColors.DOC_COMMENT_TAG).clone()); - public static final String TRANSLATED_NUMBER_ID = "GET_TEXT_TRANSLATED_NUMBER"; - public static final TextAttributesKey TRANSLATED_NUMBER = - TextAttributesKeyDefaults.createTextAttributesKey(TRANSLATED_NUMBER_ID, TextAttributesKeyDefaults - .getDefaultAttributes(SyntaxHighlighterColors.NUMBER).clone()); + public static final String NUMBER_ID = "GET_TEXT_TRANSLATED_NUMBER"; + public static final TextAttributesKey NUMBER = + TextAttributesKeyDefaults.createTextAttributesKey(NUMBER_ID, TextAttributesKeyDefaults.getDefaultAttributes(SyntaxHighlighterColors.NUMBER).clone()); public static final String BRACES_ID = "GET_TEXT_BRACES"; public static final TextAttributesKey BRACES = - TextAttributesKeyDefaults - .createTextAttributesKey(BRACES_ID, TextAttributesKeyDefaults.getDefaultAttributes(SyntaxHighlighterColors.BRACES).clone()); + TextAttributesKeyDefaults.createTextAttributesKey(BRACES_ID, TextAttributesKeyDefaults.getDefaultAttributes(SyntaxHighlighterColors.BRACES).clone()); public static final String DOTS_ID = "GET_TEXT_DOTS"; public static final TextAttributesKey DOTS = - TextAttributesKeyDefaults - .createTextAttributesKey(DOTS_ID, TextAttributesKeyDefaults.getDefaultAttributes(SyntaxHighlighterColors.DOT).clone()); - - public static final TextAttributesKey BAD_CHARACTER = - TextAttributesKeyDefaults.createTextAttributesKey("TS_BAD_CHARACTER", TextAttributesKeyDefaults - .getDefaultAttributes(HighlighterColors.BAD_CHARACTER)); + TextAttributesKeyDefaults.createTextAttributesKey(DOTS_ID, TextAttributesKeyDefaults.getDefaultAttributes(SyntaxHighlighterColors.DOT).clone()); } diff --git a/plugins/gettext/src/com/jetbrains/gettext/highlighter/GetTextSyntaxHighlighter.java b/plugins/gettext/src/com/jetbrains/gettext/highlighter/GetTextSyntaxHighlighter.java index 7719be7df13b..974120b311f2 100644 --- a/plugins/gettext/src/com/jetbrains/gettext/highlighter/GetTextSyntaxHighlighter.java +++ b/plugins/gettext/src/com/jetbrains/gettext/highlighter/GetTextSyntaxHighlighter.java @@ -3,7 +3,6 @@ package com.jetbrains.gettext.highlighter; import com.intellij.lexer.Lexer; import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.fileTypes.SyntaxHighlighterBase; -import com.intellij.psi.TokenType; import com.intellij.psi.tree.IElementType; import com.jetbrains.gettext.GetTextLexer; import com.jetbrains.gettext.GetTextTokenTypes; @@ -34,9 +33,9 @@ public class GetTextSyntaxHighlighter extends SyntaxHighlighterBase { fillMap(keys1, GetTextTokenTypes.KEYWORDS, GetTextHighlighterData.KEYWORD); fillMap(keys1, GetTextTokenTypes.STRING_LITERALS, GetTextHighlighterData.STRING); fillMap(keys1, GetTextTokenTypes.BRACES, GetTextHighlighterData.BRACES); - keys1.put(GetTextTokenTypes.NUMBER, GetTextHighlighterData.TRANSLATED_NUMBER); + fillMap(keys1, GetTextTokenTypes.NUMBERS, GetTextHighlighterData.NUMBER); keys1.put(GetTextTokenTypes.DOTS, GetTextHighlighterData.DOTS); - keys1.put(TokenType.BAD_CHARACTER, GetTextHighlighterData.BAD_CHARACTER); + keys1.put(GetTextTokenTypes.BAD_CHARACTER, GetTextHighlighterData.KEYWORD); } diff --git a/plugins/gettext/src/com/jetbrains/gettext/lang/CommandFormatException.java b/plugins/gettext/src/com/jetbrains/gettext/lang/CommandFormatException.java deleted file mode 100644 index 212465d09c2e..000000000000 --- a/plugins/gettext/src/com/jetbrains/gettext/lang/CommandFormatException.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.jetbrains.gettext.lang; - -/** - * @author Svetlana.Zemlyanskaya - */ -public class CommandFormatException extends Exception { - - public CommandFormatException(String message) { - super(message); - } -} diff --git a/plugins/gettext/src/com/jetbrains/gettext/lang/GetTextFlags.java b/plugins/gettext/src/com/jetbrains/gettext/lang/GetTextFlags.java new file mode 100644 index 000000000000..0994018079f2 --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/lang/GetTextFlags.java @@ -0,0 +1,86 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jetbrains.gettext.lang; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Svetlana.Zemlyanskaya + */ +public enum GetTextFlags { + + FUZZY("fuzzy", false), + RANGE("range", false), + C("c"), + OBJC("objc"), + SH("sh"), + PYTHON("python"), + LISP("lisp"), + ELISP("elisp"), + LIBREP("librep"), + SCHEME("scheme"), + SMALLTALK("smalltalk"), + JAVA("java"), + CSHARP("csharp"), + AWK("awk"), + YCP("ycp"), + TCL("tcl"), + PERL("perl-brace"), + PHP("php"), + GCC("gcc-internal"), + GFC("gfc-internal"), + QT("qt"), + KDE("kde"), + BOOST("boost"), + PASCAL("object-pascal"), + QT_PURAL("qt-plural"); + + + private String flagContent; + private boolean isFormatFlag; + + GetTextFlags(String flagContent, boolean formatFlag) { + this.flagContent = flagContent; + isFormatFlag = formatFlag; + } + + GetTextFlags(String flagContent) { + this.flagContent = flagContent; + this.isFormatFlag = true; + } + + public static List getAlFlags() { + List flags = new ArrayList(); + for (GetTextFlags flag : GetTextFlags.values()) { + if (flag.isFormatFlag) { + flags.add(constructFormatFlag(flag.flagContent)); + flags.add(constructNoFormatFlag(flag.flagContent)); + } else { + flags.add(flag.flagContent); + } + } + return flags; + } + + private static String constructFormatFlag(String formatContent) { + return formatContent + "-format"; + } + + private static String constructNoFormatFlag(String formatContent) { + return "no-" + constructFormatFlag(formatContent); + } +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/lang/MsgCommand.java b/plugins/gettext/src/com/jetbrains/gettext/lang/MsgCommand.java index b85fd9d6dcec..c43876be33c6 100644 --- a/plugins/gettext/src/com/jetbrains/gettext/lang/MsgCommand.java +++ b/plugins/gettext/src/com/jetbrains/gettext/lang/MsgCommand.java @@ -13,16 +13,14 @@ public abstract class MsgCommand { public abstract IElementType getCompositeElement(); - public void parse(PsiBuilder builder) throws CommandFormatException { + public boolean parse(PsiBuilder builder) { builder.advanceLexer(); int count = 0; while (builder.getTokenType() == GetTextTokenTypes.STRING) { checkString(builder); count++; } - if (count == 0) { - throw new CommandFormatException("String for " + getName() + " is not specified"); - } + return count > 0; } private static void checkString(PsiBuilder builder) { @@ -54,15 +52,8 @@ public abstract class MsgCommand { exists = true; return true; } - else if (isMultiple()) { - return true; - } - return false; + return isMultiple(); } public abstract String getName(); - - public int getCount() { - return exists ? 1 : 0; - } } diff --git a/plugins/gettext/src/com/jetbrains/gettext/lang/MsgCommandContainer.java b/plugins/gettext/src/com/jetbrains/gettext/lang/MsgCommandContainer.java index 8305aa91bd90..a0f24f79c1b8 100644 --- a/plugins/gettext/src/com/jetbrains/gettext/lang/MsgCommandContainer.java +++ b/plugins/gettext/src/com/jetbrains/gettext/lang/MsgCommandContainer.java @@ -45,17 +45,16 @@ public class MsgCommandContainer { PsiBuilder.Marker marker = builder.mark(); try { MsgCommand command = getCommand(builder.getTokenType()); - command.parse(builder); - //if (result) { + boolean result = command.parse(builder); + if (result) { marker.done(command.getCompositeElement()); - //} - //else { - // marker.error("String for " + command.getName() + " is not specified"); - //} - //return result; - return true; + } + else { + marker.error("String for " + command.getName() + " is not specified"); + } + return result; } - catch (Exception e) { + catch (UnknownCommandException e) { marker.error(e.getMessage()); builder.advanceLexer(); return false; diff --git a/plugins/gettext/src/com/jetbrains/gettext/lang/MsgstrCommand.java b/plugins/gettext/src/com/jetbrains/gettext/lang/MsgstrCommand.java index 15afdcb08002..162313381fcf 100644 --- a/plugins/gettext/src/com/jetbrains/gettext/lang/MsgstrCommand.java +++ b/plugins/gettext/src/com/jetbrains/gettext/lang/MsgstrCommand.java @@ -10,10 +10,7 @@ import com.jetbrains.gettext.GetTextTokenTypes; */ public class MsgstrCommand extends MsgCommand { - private int count; - public MsgstrCommand() { - count = 0; } @Override @@ -22,29 +19,35 @@ public class MsgstrCommand extends MsgCommand { } @Override - public void parse(PsiBuilder builder) throws CommandFormatException { - try { - super.parse(builder); - } - catch (CommandFormatException e) { - parseBraces(builder); - } - //return super.parse(builder) || parseBraces(builder); + public boolean parse(PsiBuilder builder) { + return super.parse(builder) || parseBraces(builder); } - private boolean parseBraces(PsiBuilder builder) throws CommandFormatException { + private boolean parseBraces(PsiBuilder builder) { if (builder.getTokenType() == GetTextTokenTypes.LBRACE) { builder.advanceLexer(); if (builder.getTokenType() == GetTextTokenTypes.NUMBER) { - builder.advanceLexer(); + if (!checkNumber(builder)) { + PsiBuilder.Marker marker = builder.mark(); + builder.advanceLexer(); + marker.error("Wrong number format"); + } + else { + builder.advanceLexer(); + } if (builder.getTokenType() == GetTextTokenTypes.RBRACE) { - super.parse(builder); + return super.parse(builder); } } } return false; } + private static boolean checkNumber(PsiBuilder builder) { + String number = builder.getTokenText(); + return number != null && !number.isEmpty() && !(number.charAt(0) == '0' && !number.equals("0")); + } + @Override public boolean isNecessary() { return true; @@ -59,18 +62,4 @@ public class MsgstrCommand extends MsgCommand { public String getName() { return "msgstr"; } - - @Override - public int getCount() { - return count; - } - - @Override - public boolean register() { - boolean result = super.register(); - if (result) { - count++; - } - return result; - } } diff --git a/plugins/gettext/src/com/jetbrains/gettext/parser/GetTextParser.java b/plugins/gettext/src/com/jetbrains/gettext/parser/GetTextParser.java index c0b9a0242118..cb0e1e31a9e3 100644 --- a/plugins/gettext/src/com/jetbrains/gettext/parser/GetTextParser.java +++ b/plugins/gettext/src/com/jetbrains/gettext/parser/GetTextParser.java @@ -36,7 +36,7 @@ public class GetTextParser implements PsiParser { private static void parseCommentHeader(PsiBuilder builder) { PsiBuilder.Marker marker = builder.mark(); while (GetTextTokenTypes.COMMENTS.contains(builder.getTokenType()) || - GetTextTokenTypes.FLAGS.contains(builder.getTokenType())) { + GetTextTokenTypes.FLAG_LINE.contains(builder.getTokenType())) { builder.advanceLexer(); } marker.done(GetTextCompositeElementTypes.HEADER); @@ -48,8 +48,8 @@ public class GetTextParser implements PsiParser { while (!canTerminate(builder, container)) { try { IElementType token = builder.getTokenType(); - if (container.parse(builder)) { - container.addCommand(token); + if (container.parse(builder) && !container.addCommand(token)) { + break; } } catch (UnknownCommandException e) { diff --git a/plugins/gettext/test/com/jetbrains/gettext/GetTextLexerTest.java b/plugins/gettext/test/com/jetbrains/gettext/GetTextLexerTest.java index 666bbcd73d34..27c7eb608718 100644 --- a/plugins/gettext/test/com/jetbrains/gettext/GetTextLexerTest.java +++ b/plugins/gettext/test/com/jetbrains/gettext/GetTextLexerTest.java @@ -35,10 +35,9 @@ public class GetTextLexerTest extends UsefulTestCase { } private static void doTest(String fileName) throws IOException { - final String fullPath = GetTextUtils.getFullPath(fileName); final Lexer lexer = new GetTextLexer(); - final String testText = getFileText(fullPath + ".po"); - final String expected = fullPath + ".txt"; + final String testText = getFileText(GetTextUtils.getFullSourcePath(fileName)); + final String expected = GetTextUtils.getFullLexerPath(fileName); doFileLexerTest(lexer, testText, expected); } @@ -53,7 +52,7 @@ public class GetTextLexerTest extends UsefulTestCase { } public void testLexer() throws Throwable { - doTest("string"); + doTest("command_format"); } public void testAllFiles() throws Throwable { diff --git a/plugins/gettext/test/com/jetbrains/gettext/GetTextParserTest.java b/plugins/gettext/test/com/jetbrains/gettext/GetTextParserTest.java index 6e574abfe2d7..0432a15f85cc 100644 --- a/plugins/gettext/test/com/jetbrains/gettext/GetTextParserTest.java +++ b/plugins/gettext/test/com/jetbrains/gettext/GetTextParserTest.java @@ -16,7 +16,7 @@ import java.io.IOException; public class GetTextParserTest extends LightCodeInsightFixtureTestCase { private void doTest(String fileName) throws IOException { - final String filePath = GetTextUtils.getFullPath(fileName) + ".po"; + final String filePath = GetTextUtils.getFullSourcePath(fileName); try { final String fileText = FileUtil.loadFile(new File(filePath)); @@ -30,17 +30,16 @@ public class GetTextParserTest extends LightCodeInsightFixtureTestCase { private void doTest(@NonNls final String code, final String fileName) { final PsiFile psiFile = createLightFile(fileName, GetTextLanguage.INSTANCE, code); final String tree = DebugUtil.psiTreeToString(psiFile, false); - final String path = GetTextUtils.getFullParserResultPath(fileName); + final String path = GetTextUtils.getFullParserPath(fileName); assertSameLinesWithFile(path, tree); } public void testSimple() throws IOException { - doTest("string"); + doTest("command"); } public void testAllFiles() throws Throwable { for(final String file : GetTextUtils.getAllTestedFiles()) { - System.out.println("Start: " + file); doTest(file); } } diff --git a/plugins/gettext/test/com/jetbrains/gettext/GetTextUtils.java b/plugins/gettext/test/com/jetbrains/gettext/GetTextUtils.java index d0099f4d0837..3a9ce71af357 100644 --- a/plugins/gettext/test/com/jetbrains/gettext/GetTextUtils.java +++ b/plugins/gettext/test/com/jetbrains/gettext/GetTextUtils.java @@ -6,6 +6,7 @@ import com.intellij.openapi.application.PathManager; * @author Svetlana.Zemlyanskaya */ public class GetTextUtils { + private static final String path = "community/plugins/gettext/test/com/jetbrains/gettext/"; public static String[] getAllTestedFiles() { return new String[]{ @@ -15,18 +16,25 @@ public class GetTextUtils { "complex_flags", "msg_plural", "range_flag", - "string"}; + "string", + "command_format", + "multi_id", + "command"}; } - protected static String getDataSubpath() { - return "community/plugins/gettext/test/com/jetbrains/gettext/lexer"; + private static String getFullPath() { + return PathManager.getHomePath() + "/" + path; } - public static String getFullPath(final String fileName) { - return PathManager.getHomePath() + "/" + getDataSubpath() + "/" + fileName; + public static String getFullSourcePath(final String fileName) { + return getFullPath() + "lexer/" + fileName + ".po"; } - public static String getFullParserResultPath(final String fileName) { - return getFullPath(fileName) + "_parser.txt"; + public static String getFullLexerPath(final String fileName) { + return getFullPath() + "lexer/" + fileName + ".txt"; + } + + public static String getFullParserPath(final String fileName) { + return getFullPath() + "parser/" + fileName + ".txt"; } } \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/command.po b/plugins/gettext/test/com/jetbrains/gettext/lexer/command.po new file mode 100644 index 000000000000..a173b05f51cc --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/command.po @@ -0,0 +1 @@ +msg \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/command.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/command.txt new file mode 100644 index 000000000000..d845fd46f730 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/command.txt @@ -0,0 +1 @@ +COMMAND ('msg') \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/command_format.po b/plugins/gettext/test/com/jetbrains/gettext/lexer/command_format.po new file mode 100644 index 000000000000..a46f082513b6 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/command_format.po @@ -0,0 +1,2 @@ +msgid "" +msgstr \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/command_format.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/command_format.txt new file mode 100644 index 000000000000..94128e89b9aa --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/command_format.txt @@ -0,0 +1,6 @@ +MSGID ('msgid') +WHITE_SPACE (' ') +STRING ('""') +WHITE_SPACE (' +') +MSGSTR ('msgstr') \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/complex_flags.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/complex_flags.txt index 6cb191ceaf80..cde9a830533e 100644 --- a/plugins/gettext/test/com/jetbrains/gettext/lexer/complex_flags.txt +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/complex_flags.txt @@ -4,24 +4,22 @@ COMMENT ('test') WHITE_SPACE (' ') COMMENT_SYMBOLS ('#') -COMMENT_SYMBOLS ('.') -EXTR_COMMENT (' another') +EXTR_COMMENT ('. another') WHITE_SPACE (' ') COMMENT_SYMBOLS ('#') -COMMENT_SYMBOLS (':') -REFERENCE (' ref') +REFERENCE (': ref') WHITE_SPACE (' ') COMMENT_SYMBOLS ('#') -COMMENT_SYMBOLS (',') -WHITE_SPACE (' ') +FLAG_COMMENT (',') +DELIVERY (' ') FUZZY_FLAG ('fuzzy') DELIVERY (',') -WHITE_SPACE (' ') +DELIVERY (' ') FORMAT_FLAG ('c-format') DELIVERY (',') -WHITE_SPACE (' ') +DELIVERY (' ') NO_FORMAT_FLAG ('no-objc-format') WHITE_SPACE (' ') diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/flags.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/flags.txt index 33db8a1dae30..766778232810 100644 --- a/plugins/gettext/test/com/jetbrains/gettext/lexer/flags.txt +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/flags.txt @@ -4,18 +4,16 @@ COMMENT ('test') WHITE_SPACE (' ') COMMENT_SYMBOLS ('#') -COMMENT_SYMBOLS ('.') -EXTR_COMMENT (' another') +EXTR_COMMENT ('. another') WHITE_SPACE (' ') COMMENT_SYMBOLS ('#') -COMMENT_SYMBOLS (':') -REFERENCE (' ref') +REFERENCE (': ref') WHITE_SPACE (' ') COMMENT_SYMBOLS ('#') -COMMENT_SYMBOLS (',') -WHITE_SPACE (' ') +FLAG_COMMENT (',') +DELIVERY (' ') FUZZY_FLAG ('fuzzy') DELIVERY (',') WHITE_SPACE (' diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/msg_plural.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/msg_plural.txt index 4cc17e19bbd6..fcc8aa935583 100644 --- a/plugins/gettext/test/com/jetbrains/gettext/lexer/msg_plural.txt +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/msg_plural.txt @@ -4,18 +4,15 @@ COMMENT ('test') WHITE_SPACE (' ') COMMENT_SYMBOLS ('#') -COMMENT_SYMBOLS ('.') -EXTR_COMMENT (' another') +EXTR_COMMENT ('. another') WHITE_SPACE (' ') COMMENT_SYMBOLS ('#') -COMMENT_SYMBOLS (':') -REFERENCE (' ref') +REFERENCE (': ref') WHITE_SPACE (' ') COMMENT_SYMBOLS ('#') -COMMENT_SYMBOLS ('|') -PREVIOUS_TRANSLATE_COMMENT (' msgid test') +PREVIOUS_TRANSLATE_COMMENT ('| msgid test') WHITE_SPACE (' ') MSGID_PLURAL ('msgid_plural') diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/multi_id.po b/plugins/gettext/test/com/jetbrains/gettext/lexer/multi_id.po new file mode 100644 index 000000000000..ed344f6586ec --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/multi_id.po @@ -0,0 +1,7 @@ +msgid "" +msgstr "" + +msgid "" + +msgid "" +msgstr "" \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/multi_id.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/multi_id.txt new file mode 100644 index 000000000000..40719f5ddd62 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/multi_id.txt @@ -0,0 +1,27 @@ +MSGID ('msgid') +WHITE_SPACE (' ') +STRING ('""') +WHITE_SPACE (' +') +MSGSTR ('msgstr') +WHITE_SPACE (' ') +STRING ('""') +WHITE_SPACE (' +') +WHITE_SPACE (' +') +MSGID ('msgid') +WHITE_SPACE (' ') +STRING ('""') +WHITE_SPACE (' +') +WHITE_SPACE (' +') +MSGID ('msgid') +WHITE_SPACE (' ') +STRING ('""') +WHITE_SPACE (' +') +MSGSTR ('msgstr') +WHITE_SPACE (' ') +STRING ('""') \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/range_flag.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/range_flag.txt index 60d2ec2e176a..51eed6d2ff54 100644 --- a/plugins/gettext/test/com/jetbrains/gettext/lexer/range_flag.txt +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/range_flag.txt @@ -4,27 +4,25 @@ COMMENT ('test') WHITE_SPACE (' ') COMMENT_SYMBOLS ('#') -COMMENT_SYMBOLS ('.') -EXTR_COMMENT (' another') +EXTR_COMMENT ('. another') WHITE_SPACE (' ') COMMENT_SYMBOLS ('#') -COMMENT_SYMBOLS (':') -REFERENCE (' ref') +REFERENCE (': ref') WHITE_SPACE (' ') COMMENT_SYMBOLS ('#') -COMMENT_SYMBOLS (',') -WHITE_SPACE (' ') +FLAG_COMMENT (',') +DELIVERY (' ') FUZZY_FLAG ('fuzzy') DELIVERY (',') -WHITE_SPACE (' ') +DELIVERY (' ') RANGE_FLAG ('range') COLON (':') -WHITE_SPACE (' ') -NUMBER ('0') +DELIVERY (' ') +RANGE_NUMBER ('0') DOTS ('..') -NUMBER ('10') +RANGE_NUMBER ('10') WHITE_SPACE (' ') MSGID ('msgid') diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/simple.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/simple.txt index ba45c1662815..6b18526dab75 100644 --- a/plugins/gettext/test/com/jetbrains/gettext/lexer/simple.txt +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/simple.txt @@ -4,18 +4,15 @@ COMMENT ('test') WHITE_SPACE (' ') COMMENT_SYMBOLS ('#') -COMMENT_SYMBOLS ('.') -EXTR_COMMENT (' another') +EXTR_COMMENT ('. another') WHITE_SPACE (' ') COMMENT_SYMBOLS ('#') -COMMENT_SYMBOLS (':') -REFERENCE (' ref') +REFERENCE (': ref') WHITE_SPACE (' ') COMMENT_SYMBOLS ('#') -COMMENT_SYMBOLS ('|') -PREVIOUS_TRANSLATE_COMMENT (' msgid test') +PREVIOUS_TRANSLATE_COMMENT ('| msgid test') WHITE_SPACE (' ') MSGID ('msgid') @@ -36,18 +33,15 @@ COMMENT ('t') WHITE_SPACE (' ') COMMENT_SYMBOLS ('#') -COMMENT_SYMBOLS ('.') -EXTR_COMMENT (' another') +EXTR_COMMENT ('. another') WHITE_SPACE (' ') COMMENT_SYMBOLS ('#') -COMMENT_SYMBOLS (':') -REFERENCE (' ref') +REFERENCE (': ref') WHITE_SPACE (' ') COMMENT_SYMBOLS ('#') -COMMENT_SYMBOLS ('|') -PREVIOUS_TRANSLATE_COMMENT (' msgid test') +PREVIOUS_TRANSLATE_COMMENT ('| msgid test') WHITE_SPACE (' ') MSGID ('msgid') diff --git a/plugins/gettext/test/com/jetbrains/gettext/parser/command.txt b/plugins/gettext/test/com/jetbrains/gettext/parser/command.txt new file mode 100644 index 000000000000..762a4108700e --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/parser/command.txt @@ -0,0 +1,8 @@ +GNU GetText File + MSG_BLOCK + HEADER + + PsiErrorElement:Not enough commands + PsiErrorElement:Unexpected token + + PsiElement(COMMAND)('msg') \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/parser/command_format.txt b/plugins/gettext/test/com/jetbrains/gettext/parser/command_format.txt new file mode 100644 index 000000000000..9d3f738d9b6e --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/parser/command_format.txt @@ -0,0 +1,12 @@ +GNU GetText File + MSG_BLOCK + HEADER + + PsiErrorElement:Not enough commands + MSGID + PsiElement(MSGID)('msgid') + PsiWhiteSpace(' ') + PsiElement(STRING)('""') + PsiWhiteSpace('\n') + PsiErrorElement:String for msgstr is not specified + PsiElement(MSGSTR)('msgstr') \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/complex_flags_parser.txt b/plugins/gettext/test/com/jetbrains/gettext/parser/complex_flags.txt similarity index 75% rename from plugins/gettext/test/com/jetbrains/gettext/lexer/complex_flags_parser.txt rename to plugins/gettext/test/com/jetbrains/gettext/parser/complex_flags.txt index 84ee7f7463e1..6a14a16a7bf8 100644 --- a/plugins/gettext/test/com/jetbrains/gettext/lexer/complex_flags_parser.txt +++ b/plugins/gettext/test/com/jetbrains/gettext/parser/complex_flags.txt @@ -4,24 +4,22 @@ GNU GetText File PsiComment(COMMENT)('test') PsiWhiteSpace('\n') PsiComment(COMMENT_SYMBOLS)('#') - PsiComment(COMMENT_SYMBOLS)('.') MSG_BLOCK HEADER - PsiElement(EXTR_COMMENT)(' another') + PsiElement(EXTR_COMMENT)('. another') PsiWhiteSpace('\n') PsiComment(COMMENT_SYMBOLS)('#') - PsiComment(COMMENT_SYMBOLS)(':') - PsiElement(REFERENCE)(' ref') + PsiElement(REFERENCE)(': ref') PsiWhiteSpace('\n') PsiComment(COMMENT_SYMBOLS)('#') - PsiComment(COMMENT_SYMBOLS)(',') - PsiWhiteSpace(' ') + PsiElement(FLAG_COMMENT)(',') + PsiElement(DELIVERY)(' ') PsiElement(FUZZY_FLAG)('fuzzy') PsiElement(DELIVERY)(',') - PsiWhiteSpace(' ') + PsiElement(DELIVERY)(' ') PsiElement(FORMAT_FLAG)('c-format') PsiElement(DELIVERY)(',') - PsiWhiteSpace(' ') + PsiElement(DELIVERY)(' ') PsiElement(NO_FORMAT_FLAG)('no-objc-format') PsiWhiteSpace('\n') MSG_CONTENT diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/flags_parser.txt b/plugins/gettext/test/com/jetbrains/gettext/parser/flags.txt similarity index 76% rename from plugins/gettext/test/com/jetbrains/gettext/lexer/flags_parser.txt rename to plugins/gettext/test/com/jetbrains/gettext/parser/flags.txt index 039070d56e50..f605b0127a93 100644 --- a/plugins/gettext/test/com/jetbrains/gettext/lexer/flags_parser.txt +++ b/plugins/gettext/test/com/jetbrains/gettext/parser/flags.txt @@ -4,18 +4,16 @@ GNU GetText File PsiComment(COMMENT)('test') PsiWhiteSpace('\n') PsiComment(COMMENT_SYMBOLS)('#') - PsiComment(COMMENT_SYMBOLS)('.') MSG_BLOCK HEADER - PsiElement(EXTR_COMMENT)(' another') + PsiElement(EXTR_COMMENT)('. another') PsiWhiteSpace('\n') PsiComment(COMMENT_SYMBOLS)('#') - PsiComment(COMMENT_SYMBOLS)(':') - PsiElement(REFERENCE)(' ref') + PsiElement(REFERENCE)(': ref') PsiWhiteSpace('\n') PsiComment(COMMENT_SYMBOLS)('#') - PsiComment(COMMENT_SYMBOLS)(',') - PsiWhiteSpace(' ') + PsiElement(FLAG_COMMENT)(',') + PsiElement(DELIVERY)(' ') PsiElement(FUZZY_FLAG)('fuzzy') PsiElement(DELIVERY)(',') PsiWhiteSpace('\n') diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/msg_plural_parser.txt b/plugins/gettext/test/com/jetbrains/gettext/parser/msg_plural.txt similarity index 79% rename from plugins/gettext/test/com/jetbrains/gettext/lexer/msg_plural_parser.txt rename to plugins/gettext/test/com/jetbrains/gettext/parser/msg_plural.txt index d9707ff13dc7..b4b8f9df72b2 100644 --- a/plugins/gettext/test/com/jetbrains/gettext/lexer/msg_plural_parser.txt +++ b/plugins/gettext/test/com/jetbrains/gettext/parser/msg_plural.txt @@ -4,18 +4,15 @@ GNU GetText File PsiComment(COMMENT)('test') PsiWhiteSpace('\n') PsiComment(COMMENT_SYMBOLS)('#') - PsiComment(COMMENT_SYMBOLS)('.') MSG_BLOCK HEADER - PsiElement(EXTR_COMMENT)(' another') + PsiElement(EXTR_COMMENT)('. another') PsiWhiteSpace('\n') PsiComment(COMMENT_SYMBOLS)('#') - PsiComment(COMMENT_SYMBOLS)(':') - PsiElement(REFERENCE)(' ref') + PsiElement(REFERENCE)(': ref') PsiWhiteSpace('\n') PsiComment(COMMENT_SYMBOLS)('#') - PsiComment(COMMENT_SYMBOLS)('|') - PsiElement(PREVIOUS_TRANSLATE_COMMENT)(' msgid test') + PsiElement(PREVIOUS_TRANSLATE_COMMENT)('| msgid test') PsiWhiteSpace('\n') MSG_CONTENT MSGID_PLURAL @@ -39,7 +36,8 @@ GNU GetText File MSGSTR PsiElement(MSGSTR)('msgstr') PsiElement(LBRACE)('[') - PsiElement(NUMBER)('01') + PsiErrorElement:Wrong number format + PsiElement(NUMBER)('01') PsiElement(RBRACE)(']') PsiWhiteSpace(' ') PsiElement(STRING)('"translated string"') \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/parser/multi_id.txt b/plugins/gettext/test/com/jetbrains/gettext/parser/multi_id.txt new file mode 100644 index 000000000000..5c3b1c6a3bd1 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/parser/multi_id.txt @@ -0,0 +1,39 @@ +GNU GetText File + MSG_BLOCK + HEADER + + MSG_CONTENT + MSGID + PsiElement(MSGID)('msgid') + PsiWhiteSpace(' ') + PsiElement(STRING)('""') + PsiWhiteSpace('\n') + MSGSTR + PsiElement(MSGSTR)('msgstr') + PsiWhiteSpace(' ') + PsiElement(STRING)('""') + PsiWhiteSpace('\n') + PsiWhiteSpace('\n') + MSG_BLOCK + HEADER + + PsiErrorElement:Not enough commands + MSGID + PsiElement(MSGID)('msgid') + PsiWhiteSpace(' ') + PsiElement(STRING)('""') + PsiWhiteSpace('\n') + PsiWhiteSpace('\n') + MSGID + PsiElement(MSGID)('msgid') + PsiWhiteSpace(' ') + PsiElement(STRING)('""') + PsiWhiteSpace('\n') + MSG_BLOCK + HEADER + + PsiErrorElement:Not enough commands + MSGSTR + PsiElement(MSGSTR)('msgstr') + PsiWhiteSpace(' ') + PsiElement(STRING)('""') \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/parser_parser.txt b/plugins/gettext/test/com/jetbrains/gettext/parser/parser.txt similarity index 100% rename from plugins/gettext/test/com/jetbrains/gettext/lexer/parser_parser.txt rename to plugins/gettext/test/com/jetbrains/gettext/parser/parser.txt diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/range_flag_parser.txt b/plugins/gettext/test/com/jetbrains/gettext/parser/range_flag.txt similarity index 57% rename from plugins/gettext/test/com/jetbrains/gettext/lexer/range_flag_parser.txt rename to plugins/gettext/test/com/jetbrains/gettext/parser/range_flag.txt index 46048336c942..4fdb2678507f 100644 --- a/plugins/gettext/test/com/jetbrains/gettext/lexer/range_flag_parser.txt +++ b/plugins/gettext/test/com/jetbrains/gettext/parser/range_flag.txt @@ -4,37 +4,27 @@ GNU GetText File PsiComment(COMMENT)('test') PsiWhiteSpace('\n') PsiComment(COMMENT_SYMBOLS)('#') - PsiComment(COMMENT_SYMBOLS)('.') MSG_BLOCK HEADER - PsiElement(EXTR_COMMENT)(' another') + PsiElement(EXTR_COMMENT)('. another') PsiWhiteSpace('\n') PsiComment(COMMENT_SYMBOLS)('#') - PsiComment(COMMENT_SYMBOLS)(':') - PsiElement(REFERENCE)(' ref') + PsiElement(REFERENCE)(': ref') PsiWhiteSpace('\n') PsiComment(COMMENT_SYMBOLS)('#') - PsiComment(COMMENT_SYMBOLS)(',') - PsiWhiteSpace(' ') + PsiElement(FLAG_COMMENT)(',') + PsiElement(DELIVERY)(' ') PsiElement(FUZZY_FLAG)('fuzzy') PsiElement(DELIVERY)(',') - PsiWhiteSpace(' ') + PsiElement(DELIVERY)(' ') PsiElement(RANGE_FLAG)('range') - MSG_CONTENT - PsiErrorElement:Unexpected token - PsiElement(COLON)(':') - PsiErrorElement:Unexpected token - - PsiWhiteSpace(' ') - PsiElement(NUMBER)('0') - PsiErrorElement:Unexpected token - + PsiElement(DELIVERY)(' ') + PsiElement(RANGE_NUMBER)('0') PsiElement(DOTS)('..') - PsiErrorElement:Unexpected token - - PsiElement(NUMBER)('10') - PsiWhiteSpace('\n') + PsiElement(RANGE_NUMBER)('10') + PsiWhiteSpace('\n') + MSG_CONTENT MSGID PsiElement(MSGID)('msgid') PsiWhiteSpace(' ') diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/simple_parser.txt b/plugins/gettext/test/com/jetbrains/gettext/parser/simple.txt similarity index 72% rename from plugins/gettext/test/com/jetbrains/gettext/lexer/simple_parser.txt rename to plugins/gettext/test/com/jetbrains/gettext/parser/simple.txt index 5250fbc94eb3..8b1fc6b4856d 100644 --- a/plugins/gettext/test/com/jetbrains/gettext/lexer/simple_parser.txt +++ b/plugins/gettext/test/com/jetbrains/gettext/parser/simple.txt @@ -4,18 +4,15 @@ GNU GetText File PsiComment(COMMENT)('test') PsiWhiteSpace('\n') PsiComment(COMMENT_SYMBOLS)('#') - PsiComment(COMMENT_SYMBOLS)('.') MSG_BLOCK HEADER - PsiElement(EXTR_COMMENT)(' another') + PsiElement(EXTR_COMMENT)('. another') PsiWhiteSpace('\n') PsiComment(COMMENT_SYMBOLS)('#') - PsiComment(COMMENT_SYMBOLS)(':') - PsiElement(REFERENCE)(' ref') + PsiElement(REFERENCE)(': ref') PsiWhiteSpace('\n') PsiComment(COMMENT_SYMBOLS)('#') - PsiComment(COMMENT_SYMBOLS)('|') - PsiElement(PREVIOUS_TRANSLATE_COMMENT)(' msgid test') + PsiElement(PREVIOUS_TRANSLATE_COMMENT)('| msgid test') PsiWhiteSpace('\n') MSG_CONTENT MSGID @@ -34,18 +31,15 @@ GNU GetText File PsiComment(COMMENT)('t') PsiWhiteSpace('\n') PsiComment(COMMENT_SYMBOLS)('#') - PsiComment(COMMENT_SYMBOLS)('.') MSG_BLOCK HEADER - PsiElement(EXTR_COMMENT)(' another') + PsiElement(EXTR_COMMENT)('. another') PsiWhiteSpace('\n') PsiComment(COMMENT_SYMBOLS)('#') - PsiComment(COMMENT_SYMBOLS)(':') - PsiElement(REFERENCE)(' ref') + PsiElement(REFERENCE)(': ref') PsiWhiteSpace('\n') PsiComment(COMMENT_SYMBOLS)('#') - PsiComment(COMMENT_SYMBOLS)('|') - PsiElement(PREVIOUS_TRANSLATE_COMMENT)(' msgid test') + PsiElement(PREVIOUS_TRANSLATE_COMMENT)('| msgid test') PsiWhiteSpace('\n') MSG_CONTENT MSGID diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/string_parser.txt b/plugins/gettext/test/com/jetbrains/gettext/parser/string.txt similarity index 100% rename from plugins/gettext/test/com/jetbrains/gettext/lexer/string_parser.txt rename to plugins/gettext/test/com/jetbrains/gettext/parser/string.txt diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/without_comments_parser.txt b/plugins/gettext/test/com/jetbrains/gettext/parser/without_comments.txt similarity index 100% rename from plugins/gettext/test/com/jetbrains/gettext/lexer/without_comments_parser.txt rename to plugins/gettext/test/com/jetbrains/gettext/parser/without_comments.txt diff --git a/plugins/git4idea/src/git4idea/annotate/GitFileAnnotation.java b/plugins/git4idea/src/git4idea/annotate/GitFileAnnotation.java index a18a99b85e89..ca4a9584975e 100644 --- a/plugins/git4idea/src/git4idea/annotate/GitFileAnnotation.java +++ b/plugins/git4idea/src/git4idea/annotate/GitFileAnnotation.java @@ -17,6 +17,7 @@ package git4idea.annotate; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vcs.FileStatus; import com.intellij.openapi.vcs.FileStatusListener; import com.intellij.openapi.vcs.FileStatusManager; @@ -124,7 +125,7 @@ public class GitFileAnnotation implements FileAnnotation { myFileListener = new VirtualFileAdapter() { @Override public void contentsChanged(final VirtualFileEvent event) { - if (myFile != event.getFile()) return; + if (!Comparing.equal(myFile, event.getFile())) return; if (!event.isFromRefresh()) return; final VcsRevisionNumber currentRevision = myVcs.getDiffProvider().getCurrentRevision(myFile); if (currentRevision != null && currentRevision.equals(revision)) return; diff --git a/plugins/git4idea/src/git4idea/status/GitOldChangesCollector.java b/plugins/git4idea/src/git4idea/status/GitOldChangesCollector.java index 518efac8ca8d..8fbf943bb111 100644 --- a/plugins/git4idea/src/git4idea/status/GitOldChangesCollector.java +++ b/plugins/git4idea/src/git4idea/status/GitOldChangesCollector.java @@ -16,6 +16,7 @@ package git4idea.status; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vcs.*; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.ChangeListManager; @@ -226,7 +227,7 @@ class GitOldChangesCollector extends GitChangesCollector { sc.skipChars(2); if ('?' == status) { VirtualFile file = myVcsRoot.findFileByRelativePath(GitUtil.unescapePath(sc.line())); - if (GitUtil.gitRootOrNull(file) == myVcsRoot) { + if (Comparing.equal(GitUtil.gitRootOrNull(file), myVcsRoot)) { myUnversioned.add(file); } } @@ -235,7 +236,7 @@ class GitOldChangesCollector extends GitChangesCollector { sc.boundedToken('\t'); String file = GitUtil.unescapePath(sc.line()); VirtualFile vFile = myVcsRoot.findFileByRelativePath(file); - if (GitUtil.gitRootOrNull(vFile) != myVcsRoot) { + if (!Comparing.equal(GitUtil.gitRootOrNull(vFile), myVcsRoot)) { continue; } if (!myUnmergedNames.add(file)) { diff --git a/plugins/git4idea/src/git4idea/ui/GitRefspecPanel.java b/plugins/git4idea/src/git4idea/ui/GitRefspecPanel.java index b64fd47a42a1..52b128b0b3c0 100644 --- a/plugins/git4idea/src/git4idea/ui/GitRefspecPanel.java +++ b/plugins/git4idea/src/git4idea/ui/GitRefspecPanel.java @@ -17,6 +17,7 @@ package git4idea.ui; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.DocumentAdapter; @@ -308,7 +309,7 @@ public class GitRefspecPanel extends JPanel { * @param gitRoot a git root */ public void setGitRoot(final VirtualFile gitRoot) { - if (gitRoot == myGitRoot) { + if (Comparing.equal(gitRoot, myGitRoot)) { return; } myGitRoot = gitRoot; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureUtil.java index 61cbb2593255..fa8c9d30ac39 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureUtil.java @@ -70,7 +70,7 @@ public class MvcModuleStructureUtil { @Nullable public static ContentEntry findContentEntry(ModuleRootModel rootModel, VirtualFile root) { for (ContentEntry entry : rootModel.getContentEntries()) { - if (entry.getFile() == root) { + if (Comparing.equal(entry.getFile(), root)) { return entry; } } @@ -147,7 +147,7 @@ public class MvcModuleStructureUtil { public void consume(ContentEntry contentEntry) { SourceFolder[] folders = contentEntry.getSourceFolders(); for (SourceFolder folder : folders) { - if (folder.getFile() == file) { + if (Comparing.equal(folder.getFile(), file)) { contentEntry.removeSourceFolder(folder); } } @@ -218,7 +218,7 @@ public class MvcModuleStructureUtil { @Override public void consume(ContentEntry entry) { for (SourceFolder folder : entry.getSourceFolders()) { - if (folder.getFile() == src) { + if (Comparing.equal(folder.getFile(), src)) { entry.removeSourceFolder(folder); entry.addSourceFolder(src, isTest, ""); break; @@ -795,7 +795,7 @@ public class MvcModuleStructureUtil { } else { for (int i = 1; i < contentRoots.length; i++) { - if (parent != contentRoots[i].getParent()) { + if (!Comparing.equal(parent, contentRoots[i].getParent())) { parent = null; break; } diff --git a/plugins/junit_rt/src/com/intellij/junit3/TestAllInPackage2.java b/plugins/junit_rt/src/com/intellij/junit3/TestAllInPackage2.java index 9d9b166aa492..58aff128624f 100644 --- a/plugins/junit_rt/src/com/intellij/junit3/TestAllInPackage2.java +++ b/plugins/junit_rt/src/com/intellij/junit3/TestAllInPackage2.java @@ -38,9 +38,17 @@ public class TestAllInPackage2 extends TestSuite { String classMethodName = classMethodNames[i]; Test suite = TestRunnerUtil.createClassOrMethodSuite(runner, classMethodName); if (suite != null) { - final boolean isTestSuite = suite instanceof TestSuite; - if (!isTestSuite || allNames.contains(((TestSuite)suite).getName())) { - if (isTestSuite && ((TestSuite)suite).getName() == null) { + boolean skip; + if (suite instanceof TestSuite) { + skip = !allNames.contains(((TestSuite)suite).getName()); + } else if (suite instanceof TestRunnerUtil.SuiteMethodWrapper) { + skip = !allNames.contains(((TestRunnerUtil.SuiteMethodWrapper)suite).getClassName()); + } else { + skip = false; + } + + if (!skip) { + if (suite instanceof TestSuite && ((TestSuite)suite).getName() == null) { attachSuiteInfo(suite, classMethodName); } addTest(suite); @@ -56,13 +64,19 @@ public class TestAllInPackage2 extends TestSuite { if (suite instanceof TestRunnerUtil.SuiteMethodWrapper) { final Test test = ((TestRunnerUtil.SuiteMethodWrapper)suite).getSuite(); final String currentSuiteName = ((TestRunnerUtil.SuiteMethodWrapper)suite).getClassName(); - if (test instanceof TestSuite) { - for (int idx = 0; idx < ((TestSuite)test).testCount(); idx++) { - final String testName = ((TestSuite)test).testAt(idx).toString(); - if (!currentSuiteName.equals(testName)) { - allNames.remove(testName); - } + skipSubtests(allNames, test, currentSuiteName); + } + } + + private static void skipSubtests(Set allNames, Test test, String currentSuiteName) { + if (test instanceof TestSuite) { + for (int idx = 0; idx < ((TestSuite)test).testCount(); idx++) { + Test childTest = ((TestSuite)test).testAt(idx); + final String testName = childTest.toString(); + if (!currentSuiteName.equals(testName)) { + allNames.remove(testName); } + skipSubtests(allNames, childTest, currentSuiteName); } } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomUtil.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomUtil.java index b1906ff44f2b..169080277b91 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomUtil.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomUtil.java @@ -22,6 +22,7 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; @@ -155,7 +156,7 @@ public class MavenDomUtil { result.getArtifactId().setStringValue(parentId.getArtifactId()); result.getVersion().setStringValue(parentId.getVersion()); - if (pomFile.getParent().getParent() != parentProject.getDirectoryFile()) { + if (!Comparing.equal(pomFile.getParent().getParent(), parentProject.getDirectoryFile())) { result.getRelativePath().setValue(PsiManager.getInstance(project).findFile(parentProject.getFile())); } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/annotator/MavenDomAnnotator.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/annotator/MavenDomAnnotator.java index 1227c5e913bc..fedf17ea23ad 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/annotator/MavenDomAnnotator.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/annotator/MavenDomAnnotator.java @@ -20,6 +20,7 @@ import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.xml.DomElement; @@ -59,7 +60,7 @@ public class MavenDomAnnotator implements DomElementsAnnotator { VirtualFile problemFile = LocalFileSystem.getInstance().findFileByPath(each.getPath()); LocalQuickFix[] fixes = LocalQuickFix.EMPTY_ARRAY; - if (problemFile != null && mavenProject.getFile() != problemFile) { + if (problemFile != null && !Comparing.equal(mavenProject.getFile(), problemFile)) { fixes = new LocalQuickFix[]{new OpenProblemFileFix(problemFile)}; } holder.createProblem(element, HighlightSeverity.ERROR, each.getDescription(), fixes); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenModulePsiReference.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenModulePsiReference.java index 56efcf6de5df..2909cb467231 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenModulePsiReference.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenModulePsiReference.java @@ -20,6 +20,7 @@ import com.intellij.codeInspection.LocalQuickFix; import com.intellij.codeInspection.LocalQuickFixProvider; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VfsUtil; @@ -64,7 +65,7 @@ public class MavenModulePsiReference extends MavenPsiReference implements LocalQ for (DomFileElement eachDomFile : files) { VirtualFile eachVFile = eachDomFile.getOriginalFile().getVirtualFile(); - if (eachVFile == myVirtualFile) continue; + if (Comparing.equal(eachVFile, myVirtualFile)) continue; PsiFile psiFile = eachDomFile.getFile(); String modulePath = calcRelativeModulePath(myVirtualFile, eachVFile); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenParentProjectFileProcessor.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenParentProjectFileProcessor.java index 6c243cbaa20d..205a7de78aef 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenParentProjectFileProcessor.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenParentProjectFileProcessor.java @@ -15,6 +15,7 @@ */ package org.jetbrains.idea.maven.project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; @@ -31,7 +32,7 @@ public abstract class MavenParentProjectFileProcessor { @NotNull VirtualFile projectFile, @Nullable MavenParentDesc parentDesc) { VirtualFile superPom = generalSettings.getEffectiveSuperPom(); - if (projectFile == superPom) return null; + if (Comparing.equal(projectFile, superPom)) return null; RESULT_TYPE result = null; diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java index 2b5d4c68a5d4..694597e93d24 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java @@ -346,7 +346,7 @@ public class MavenProjectsManagerWatcher { private boolean isSettingsFile(VirtualFile f) { for (VirtualFilePointer each : mySettingsFilesPointers) { - if (each.getFile() == f) return true; + if (Comparing.equal(each.getFile(), f)) return true; } return false; } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java index 0a044cd42563..925792a728d3 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java @@ -1,723 +1,724 @@ -/* - * Copyright 2000-2009 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.idea.maven.utils; - -import com.intellij.codeInsight.template.TemplateManager; -import com.intellij.codeInsight.template.impl.TemplateImpl; -import com.intellij.execution.configurations.ParametersList; -import com.intellij.ide.fileTemplates.FileTemplate; -import com.intellij.ide.fileTemplates.FileTemplateManager; -import com.intellij.notification.Notification; -import com.intellij.notification.NotificationType; -import com.intellij.notification.Notifications; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ModalityState; -import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.application.impl.LaterInvocator; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.fileEditor.FileEditorManager; -import com.intellij.openapi.fileEditor.OpenFileDescriptor; -import com.intellij.openapi.progress.ProcessCanceledException; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.progress.ProgressManager; -import com.intellij.openapi.progress.Task; -import com.intellij.openapi.project.DumbService; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.startup.StartupManager; -import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.SystemInfo; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.JarFileSystem; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.Function; -import com.intellij.util.SystemProperties; -import com.intellij.util.containers.ContainerUtil; -import gnu.trove.THashSet; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.idea.maven.model.MavenConstants; -import org.jetbrains.idea.maven.model.MavenId; -import org.jetbrains.idea.maven.project.MavenProject; -import org.jetbrains.idea.maven.server.MavenServerManager; -import org.jetbrains.idea.maven.server.MavenServerUtil; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.util.*; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; - -public class MavenUtil { - public static final String MAVEN_NOTIFICATION_GROUP = "Maven"; - public static final String SETTINGS_XML = "settings.xml"; - public static final String DOT_M2_DIR = ".m2"; - public static final String PROP_USER_HOME = "user.home"; - public static final String ENV_M2_HOME = "M2_HOME"; - public static final String M2_DIR = "m2"; - public static final String BIN_DIR = "bin"; - public static final String CONF_DIR = "conf"; - public static final String M2_CONF_FILE = "m2.conf"; - public static final String REPOSITORY_DIR = "repository"; - public static final String LIB_DIR = "lib"; - - @SuppressWarnings("unchecked") - private static final Pair[] SUPER_POM_PATHS = new Pair[]{ - Pair.create(Pattern.compile("maven-\\d+\\.\\d+\\.\\d+-uber\\.jar"), "org/apache/maven/project/" + MavenConstants.SUPER_POM_XML), - Pair.create(Pattern.compile("maven-model-builder-\\d+\\.\\d+\\.\\d+\\.jar"), "org/apache/maven/model/" + MavenConstants.SUPER_POM_XML) - }; - - private static volatile Map ourPropertiesFromMvnOpts; - - public static Map getPropertiesFromMavenOpts() { - Map res = ourPropertiesFromMvnOpts; - if (res == null) { - String mavenOpts = System.getenv("MAVEN_OPTS"); - if (mavenOpts != null) { - ParametersList mavenOptsList = new ParametersList(); - mavenOptsList.addParametersString(mavenOpts); - res = mavenOptsList.getProperties(); - } - else { - res = Collections.emptyMap(); - } - - ourPropertiesFromMvnOpts = res; - } - - return res; - } - - - public static void invokeLater(Project p, Runnable r) { - invokeLater(p, ModalityState.defaultModalityState(), r); - } - - public static void invokeLater(final Project p, final ModalityState state, final Runnable r) { - if (isNoBackgroundMode()) { - r.run(); - } - else { - ApplicationManager.getApplication().invokeLater(new Runnable() { - public void run() { - if (p.isDisposed()) return; - r.run(); - } - }, state); - } - } - - public static void invokeAndWait(Project p, Runnable r) { - invokeAndWait(p, ModalityState.defaultModalityState(), r); - } - - public static void invokeAndWait(final Project p, final ModalityState state, final Runnable r) { - if (isNoBackgroundMode()) { - r.run(); - } - else { - if (ApplicationManager.getApplication().isDispatchThread()) { - r.run(); - } - else { - ApplicationManager.getApplication().invokeAndWait(new Runnable() { - public void run() { - if (p.isDisposed()) return; - r.run(); - } - }, state); - } - } - } - - public static void invokeAndWaitWriteAction(Project p, final Runnable r) { - invokeAndWait(p, new Runnable() { - public void run() { - ApplicationManager.getApplication().runWriteAction(r); - } - }); - } - - public static void runDumbAware(final Project project, final Runnable r) { - if (DumbService.isDumbAware(r)) { - r.run(); - } - else { - DumbService.getInstance(project).runWhenSmart(new Runnable() { - public void run() { - if (project.isDisposed()) return; - r.run(); - } - }); - } - } - - public static void runWhenInitialized(final Project project, final Runnable r) { - if (project.isDisposed()) return; - - if (isNoBackgroundMode()) { - r.run(); - return; - } - - if (!project.isInitialized()) { - StartupManager.getInstance(project).registerPostStartupActivity(r); - return; - } - - runDumbAware(project, r); - } - - public static boolean isNoBackgroundMode() { - return (ApplicationManager.getApplication().isUnitTestMode() - || ApplicationManager.getApplication().isHeadlessEnvironment()); - } - - public static boolean isInModalContext() { - if (isNoBackgroundMode()) return false; - return LaterInvocator.isInModalContext(); - } - - public static void showError(Project project, String title, Throwable e) { - MavenLog.LOG.warn(title, e); - Notifications.Bus.notify(new Notification(MAVEN_NOTIFICATION_GROUP, title, e.getMessage(), NotificationType.ERROR), project); - } - - public static Properties getSystemProperties() { - Properties result = (Properties)System.getProperties().clone(); - for (String each : new THashSet((Set)result.keySet())) { - if (each.startsWith("idea.")) { - result.remove(each); - } - } - return result; - } - - public static Properties getEnvProperties() { - Properties reuslt = new Properties(); - for (Map.Entry each : System.getenv().entrySet()) { - if (isMagicalProperty(each.getKey())) continue; - reuslt.put(each.getKey(), each.getValue()); - } - return reuslt; - } - - private static boolean isMagicalProperty(String key) { - return key.startsWith("="); - } - - public static File getPluginSystemDir(String folder) { - // PathManager.getSystemPath() may return relative path - return new File(PathManager.getSystemPath(), "Maven" + "/" + folder).getAbsoluteFile(); - } - - public static VirtualFile findProfilesXmlFile(VirtualFile pomFile) { - return pomFile.getParent().findChild(MavenConstants.PROFILES_XML); - } - - public static File getProfilesXmlIoFile(VirtualFile pomFile) { - return new File(pomFile.getParent().getPath(), MavenConstants.PROFILES_XML); - } - - public static List collectFirsts(List> pairs) { - List result = new ArrayList(pairs.size()); - for (Pair each : pairs) { - result.add(each.first); - } - return result; - } - - public static List collectSeconds(List> pairs) { - List result = new ArrayList(pairs.size()); - for (Pair each : pairs) { - result.add(each.second); - } - return result; - } - - public static List collectPaths(List files) { - return ContainerUtil.map(files, new Function() { - public String fun(VirtualFile file) { - return file.getPath(); - } - }); - } - - public static List collectFiles(Collection projects) { - return ContainerUtil.map(projects, new Function() { - public VirtualFile fun(MavenProject project) { - return project.getFile(); - } - }); - } - - public static boolean equalAsSets(final Collection collection1, final Collection collection2) { - return toSet(collection1).equals(toSet(collection2)); - } - - private static Collection toSet(final Collection collection) { - return (collection instanceof Set ? collection : new THashSet(collection)); - } - - public static List> mapToList(Map map) { - return ContainerUtil.map2List(map.entrySet(), new Function, Pair>() { - public Pair fun(Map.Entry tuEntry) { - return Pair.create(tuEntry.getKey(), tuEntry.getValue()); - } - }); - } - - public static String formatHtmlImage(URL url) { - return " "; - } - - public static void runOrApplyMavenProjectFileTemplate(Project project, - VirtualFile file, - MavenId projectId, - boolean interactive) throws IOException { - runOrApplyMavenProjectFileTemplate(project, file, projectId, null, null, interactive); - } - - public static void runOrApplyMavenProjectFileTemplate(Project project, - VirtualFile file, - MavenId projectId, - MavenId parentId, - VirtualFile parentFile, - boolean interactive) throws IOException { - Properties properties = new Properties(); - Properties conditions = new Properties(); - properties.setProperty("GROUP_ID", projectId.getGroupId()); - properties.setProperty("ARTIFACT_ID", projectId.getArtifactId()); - properties.setProperty("VERSION", projectId.getVersion()); - if (parentId != null) { - conditions.setProperty("HAS_PARENT", "true"); - properties.setProperty("PARENT_GROUP_ID", parentId.getGroupId()); - properties.setProperty("PARENT_ARTIFACT_ID", parentId.getArtifactId()); - properties.setProperty("PARENT_VERSION", parentId.getVersion()); - - if (parentFile != null) { - VirtualFile modulePath = file.getParent(); - VirtualFile parentModulePath = parentFile.getParent(); - - if (modulePath.getParent() != parentModulePath) { - String relativePath = VfsUtil.getPath(file, parentModulePath, '/'); - if (relativePath != null) { - if (relativePath.endsWith("/")) relativePath = relativePath.substring(0, relativePath.length() - 1); - - conditions.setProperty("HAS_RELATIVE_PATH", "true"); - properties.setProperty("PARENT_RELATIVE_PATH", relativePath); - } - } - } - } - runOrApplyFileTemplate(project, file, MavenFileTemplateGroupFactory.MAVEN_PROJECT_XML_TEMPLATE, properties, conditions, interactive); - } - - public static void runFileTemplate(Project project, - VirtualFile file, - String templateName) throws IOException { - runOrApplyFileTemplate(project, file, templateName, new Properties(), new Properties(), true); - } - - private static void runOrApplyFileTemplate(Project project, - VirtualFile file, - String templateName, - Properties properties, - Properties conditions, - boolean interactive) throws IOException { - FileTemplateManager manager = FileTemplateManager.getInstance(); - FileTemplate fileTemplate = manager.getJ2eeTemplate(templateName); - Properties allProperties = manager.getDefaultProperties(project); - if (!interactive) { - allProperties.putAll(properties); - } - allProperties.putAll(conditions); - String text = fileTemplate.getText(allProperties); - Pattern pattern = Pattern.compile("\\$\\{(.*)\\}"); - Matcher matcher = pattern.matcher(text); - StringBuffer builder = new StringBuffer(); - while (matcher.find()) { - matcher.appendReplacement(builder, "\\$" + matcher.group(1).toUpperCase() + "\\$"); - } - matcher.appendTail(builder); - text = builder.toString(); - - TemplateImpl template = (TemplateImpl)TemplateManager.getInstance(project).createTemplate("", "", text); - for (int i = 0; i < template.getSegmentsCount(); i++) { - if (i == template.getEndSegmentNumber()) continue; - String name = template.getSegmentName(i); - String value = "\"" + properties.getProperty(name, "") + "\""; - template.addVariable(name, value, value, true); - } - - if (interactive) { - OpenFileDescriptor descriptor = new OpenFileDescriptor(project, file); - Editor editor = FileEditorManager.getInstance(project).openTextEditor(descriptor, true); - editor.getDocument().setText(""); - TemplateManager.getInstance(project).startTemplate(editor, template); - } - else { - VfsUtil.saveText(file, template.getTemplateText()); - } - } - - public static > T collectPattern(String text, T result) { - String antPattern = FileUtil.convertAntToRegexp(text.trim()); - try { - result.add(Pattern.compile(antPattern)); - } - catch (PatternSyntaxException ignore) { - } - return result; - } - - public static boolean isIncluded(String relativeName, List includes, List excludes) { - boolean result = false; - for (Pattern each : includes) { - if (each.matcher(relativeName).matches()) { - result = true; - break; - } - } - if (!result) return false; - for (Pattern each : excludes) { - if (each.matcher(relativeName).matches()) return false; - } - return true; - } - - public static void run(Project project, String title, final MavenTask task) throws MavenProcessCanceledException { - final Exception[] canceledEx = new Exception[1]; - final RuntimeException[] runtimeEx = new RuntimeException[1]; - final Error[] errorEx = new Error[1]; - - ProgressManager.getInstance().run(new Task.Modal(project, title, true) { - public void run(@NotNull ProgressIndicator i) { - try { - task.run(new MavenProgressIndicator(i)); - } - catch (MavenProcessCanceledException e) { - canceledEx[0] = e; - } - catch (ProcessCanceledException e) { - canceledEx[0] = e; - } - catch (RuntimeException e) { - runtimeEx[0] = e; - } - catch (Error e) { - errorEx[0] = e; - } - } - }); - if (canceledEx[0] instanceof MavenProcessCanceledException) throw (MavenProcessCanceledException)canceledEx[0]; - if (canceledEx[0] instanceof ProcessCanceledException) throw new MavenProcessCanceledException(); - - if (runtimeEx[0] != null) throw runtimeEx[0]; - if (errorEx[0] != null) throw errorEx[0]; - } - - public static MavenTaskHandler runInBackground(final Project project, - final String title, - final boolean cancellable, - final MavenTask task) { - final MavenProgressIndicator indicator = new MavenProgressIndicator(); - - Runnable runnable = new Runnable() { - public void run() { - try { - task.run(indicator); - } - catch (MavenProcessCanceledException ignore) { - indicator.cancel(); - } - catch (ProcessCanceledException ignore) { - indicator.cancel(); - } - } - }; - - if (isNoBackgroundMode()) { - runnable.run(); - return new MavenTaskHandler() { - public void waitFor() { - } - }; - } - else { - final Future future = ApplicationManager.getApplication().executeOnPooledThread(runnable); - final MavenTaskHandler handler = new MavenTaskHandler() { - public void waitFor() { - try { - future.get(); - } - catch (InterruptedException e) { - MavenLog.LOG.error(e); - } - catch (ExecutionException e) { - MavenLog.LOG.error(e); - } - } - }; - invokeLater(project, new Runnable() { - public void run() { - if (future.isDone()) return; - new Task.Backgroundable(project, title, cancellable) { - public void run(@NotNull ProgressIndicator i) { - indicator.setIndicator(i); - handler.waitFor(); - } - }.queue(); - } - }); - return handler; - } - } - - @Nullable - public static File resolveMavenHomeDirectory(@Nullable String overrideMavenHome) { - if (!isEmptyOrSpaces(overrideMavenHome)) { - return new File(overrideMavenHome); - } - - String m2home = System.getenv(ENV_M2_HOME); - if (!isEmptyOrSpaces(m2home)) { - final File homeFromEnv = new File(m2home); - if (isValidMavenHome(homeFromEnv)) { - return homeFromEnv; - } - } - - String userHome = SystemProperties.getUserHome(); - if (!isEmptyOrSpaces(userHome)) { - final File underUserHome = new File(userHome, M2_DIR); - if (isValidMavenHome(underUserHome)) { - return underUserHome; - } - } - - if (SystemInfo.isMac) { - File home = fromBrew(); - if (home != null) { - return home; - } - - if ((home = fromMacSystemJavaTools()) != null) { - return home; - } - } - else if (SystemInfo.isLinux) { - File home = new File("/usr/share/maven2"); - if (isValidMavenHome(home)) { - return home; - } - } - - return null; - } - - @Nullable - private static File fromMacSystemJavaTools() { - final File symlinkDir = new File("/usr/share/maven"); - if (isValidMavenHome(symlinkDir)) { - return symlinkDir; - } - - // well, try to search - final File dir = new File("/usr/share/java"); - final String[] list = dir.list(); - if (list == null || list.length == 0) { - return null; - } - - String home = null; - final String prefix = "maven-"; - final int versionIndex = prefix.length(); - for (String path : list) { - if (path.startsWith(prefix) && - (home == null || StringUtil.compareVersionNumbers(path.substring(versionIndex), home.substring(versionIndex)) > 0)) { - home = path; - } - } - - if (home != null) { - File file = new File(dir, home); - if (isValidMavenHome(file)) { - return file; - } - } - - return null; - } - - @Nullable - private static File fromBrew() { - final File brewDir = new File("/usr/local/Cellar/maven"); - final String[] list = brewDir.list(); - if (list == null || list.length == 0) { - return null; - } - - if (list.length > 1) { - Arrays.sort(list, new Comparator() { - @Override - public int compare(String o1, String o2) { - return StringUtil.compareVersionNumbers(o2, o1); - } - }); - } - - final File file = new File(brewDir, list[0] + "/libexec"); - return isValidMavenHome(file) ? file : null; - } - - public static boolean isEmptyOrSpaces(@Nullable String str) { - return str == null || str.length() == 0 || str.trim().length() == 0; - } - - public static boolean isValidMavenHome(File home) { - return getMavenConfFile(home).exists(); - } - - public static File getMavenConfFile(File mavenHome) { - return new File(new File(mavenHome, BIN_DIR), M2_CONF_FILE); - } - - @Nullable - public static File resolveGlobalSettingsFile(@Nullable String overriddenMavenHome) { - File directory = resolveMavenHomeDirectory(overriddenMavenHome); - if (directory == null) return null; - - return new File(new File(directory, CONF_DIR), SETTINGS_XML); - } - - @NotNull - public static File resolveUserSettingsFile(@Nullable String overriddenUserSettingsFile) { - if (!isEmptyOrSpaces(overriddenUserSettingsFile)) return new File(overriddenUserSettingsFile); - return new File(resolveM2Dir(), SETTINGS_XML); - } - - @NotNull - public static File resolveM2Dir() { - return new File(SystemProperties.getUserHome(), DOT_M2_DIR); - } - - @NotNull - public static File resolveLocalRepository(@Nullable String overriddenLocalRepository, - @Nullable String overriddenMavenHome, - @Nullable String overriddenUserSettingsFile) { - File result = null; - if (!isEmptyOrSpaces(overriddenLocalRepository)) result = new File(overriddenLocalRepository); - if (result == null) { - result = doResolveLocalRepository(resolveUserSettingsFile(overriddenUserSettingsFile), - resolveGlobalSettingsFile(overriddenMavenHome)); - } - try { - return result.getCanonicalFile(); - } - catch (IOException e) { - return result; - } - } - - @NotNull - public static File doResolveLocalRepository(@Nullable File userSettingsFile, @Nullable File globalSettingsFile) { - if (userSettingsFile != null) { - final String fromUserSettings = getRepositoryFromSettings(userSettingsFile); - if (!StringUtil.isEmpty(fromUserSettings)) { - return new File(fromUserSettings); - } - } - - if (globalSettingsFile != null) { - final String fromGlobalSettings = getRepositoryFromSettings(globalSettingsFile); - if (!StringUtil.isEmpty(fromGlobalSettings)) { - return new File(fromGlobalSettings); - } - } - - return new File(resolveM2Dir(), REPOSITORY_DIR); - } - - @Nullable - public static String getRepositoryFromSettings(final File file) { - try { - byte[] bytes = FileUtil.loadFileBytes(file); - return expandProperties(MavenJDOMUtil.findChildValueByPath(MavenJDOMUtil.read(bytes, null), "localRepository", null)); - } - catch (IOException e) { - return null; - } - } - - public static String expandProperties(String text) { - if (StringUtil.isEmptyOrSpaces(text)) return text; - Properties props = MavenServerUtil.collectSystemProperties(); - for (Map.Entry each : props.entrySet()) { - Object val = each.getValue(); - text = text.replace("${" + each.getKey() + "}", val instanceof CharSequence ? (CharSequence)val : val.toString()); - } - return text; - } - - @NotNull - public static VirtualFile resolveSuperPomFile(@Nullable File mavenHome) { - VirtualFile result = null; - if (mavenHome != null) { - result = doResolveSuperPomFile(new File(mavenHome, LIB_DIR)); - } - if (result == null) { - result = doResolveSuperPomFile(MavenServerManager.collectClassPathAndLibsFolder().second); - } - return result; - } - - @Nullable - public static VirtualFile doResolveSuperPomFile(@NotNull File mavenHome) { - File[] files = mavenHome.listFiles(); - if (files == null) return null; - - for (File library : files) { - - for (Pair path : SUPER_POM_PATHS) { - if (path.first.matcher(library.getName()).matches()) { - VirtualFile libraryVirtualFile = LocalFileSystem.getInstance().findFileByIoFile(library); - if (libraryVirtualFile == null) continue; - - VirtualFile root = JarFileSystem.getInstance().getJarRootForLocalFile(libraryVirtualFile); - if (root == null) continue; - - VirtualFile pomFile = root.findFileByRelativePath(path.second); - if (pomFile != null) { - return pomFile; - } - } - } - } - - return null; - } - - public interface MavenTaskHandler { - void waitFor(); - } -} +/* + * Copyright 2000-2009 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.idea.maven.utils; + +import com.intellij.codeInsight.template.TemplateManager; +import com.intellij.codeInsight.template.impl.TemplateImpl; +import com.intellij.execution.configurations.ParametersList; +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationType; +import com.intellij.notification.Notifications; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.application.impl.LaterInvocator; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.Function; +import com.intellij.util.SystemProperties; +import com.intellij.util.containers.ContainerUtil; +import gnu.trove.THashSet; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.maven.model.MavenConstants; +import org.jetbrains.idea.maven.model.MavenId; +import org.jetbrains.idea.maven.project.MavenProject; +import org.jetbrains.idea.maven.server.MavenServerManager; +import org.jetbrains.idea.maven.server.MavenServerUtil; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +public class MavenUtil { + public static final String MAVEN_NOTIFICATION_GROUP = "Maven"; + public static final String SETTINGS_XML = "settings.xml"; + public static final String DOT_M2_DIR = ".m2"; + public static final String PROP_USER_HOME = "user.home"; + public static final String ENV_M2_HOME = "M2_HOME"; + public static final String M2_DIR = "m2"; + public static final String BIN_DIR = "bin"; + public static final String CONF_DIR = "conf"; + public static final String M2_CONF_FILE = "m2.conf"; + public static final String REPOSITORY_DIR = "repository"; + public static final String LIB_DIR = "lib"; + + @SuppressWarnings("unchecked") + private static final Pair[] SUPER_POM_PATHS = new Pair[]{ + Pair.create(Pattern.compile("maven-\\d+\\.\\d+\\.\\d+-uber\\.jar"), "org/apache/maven/project/" + MavenConstants.SUPER_POM_XML), + Pair.create(Pattern.compile("maven-model-builder-\\d+\\.\\d+\\.\\d+\\.jar"), "org/apache/maven/model/" + MavenConstants.SUPER_POM_XML) + }; + + private static volatile Map ourPropertiesFromMvnOpts; + + public static Map getPropertiesFromMavenOpts() { + Map res = ourPropertiesFromMvnOpts; + if (res == null) { + String mavenOpts = System.getenv("MAVEN_OPTS"); + if (mavenOpts != null) { + ParametersList mavenOptsList = new ParametersList(); + mavenOptsList.addParametersString(mavenOpts); + res = mavenOptsList.getProperties(); + } + else { + res = Collections.emptyMap(); + } + + ourPropertiesFromMvnOpts = res; + } + + return res; + } + + + public static void invokeLater(Project p, Runnable r) { + invokeLater(p, ModalityState.defaultModalityState(), r); + } + + public static void invokeLater(final Project p, final ModalityState state, final Runnable r) { + if (isNoBackgroundMode()) { + r.run(); + } + else { + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (p.isDisposed()) return; + r.run(); + } + }, state); + } + } + + public static void invokeAndWait(Project p, Runnable r) { + invokeAndWait(p, ModalityState.defaultModalityState(), r); + } + + public static void invokeAndWait(final Project p, final ModalityState state, final Runnable r) { + if (isNoBackgroundMode()) { + r.run(); + } + else { + if (ApplicationManager.getApplication().isDispatchThread()) { + r.run(); + } + else { + ApplicationManager.getApplication().invokeAndWait(new Runnable() { + public void run() { + if (p.isDisposed()) return; + r.run(); + } + }, state); + } + } + } + + public static void invokeAndWaitWriteAction(Project p, final Runnable r) { + invokeAndWait(p, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(r); + } + }); + } + + public static void runDumbAware(final Project project, final Runnable r) { + if (DumbService.isDumbAware(r)) { + r.run(); + } + else { + DumbService.getInstance(project).runWhenSmart(new Runnable() { + public void run() { + if (project.isDisposed()) return; + r.run(); + } + }); + } + } + + public static void runWhenInitialized(final Project project, final Runnable r) { + if (project.isDisposed()) return; + + if (isNoBackgroundMode()) { + r.run(); + return; + } + + if (!project.isInitialized()) { + StartupManager.getInstance(project).registerPostStartupActivity(r); + return; + } + + runDumbAware(project, r); + } + + public static boolean isNoBackgroundMode() { + return (ApplicationManager.getApplication().isUnitTestMode() + || ApplicationManager.getApplication().isHeadlessEnvironment()); + } + + public static boolean isInModalContext() { + if (isNoBackgroundMode()) return false; + return LaterInvocator.isInModalContext(); + } + + public static void showError(Project project, String title, Throwable e) { + MavenLog.LOG.warn(title, e); + Notifications.Bus.notify(new Notification(MAVEN_NOTIFICATION_GROUP, title, e.getMessage(), NotificationType.ERROR), project); + } + + public static Properties getSystemProperties() { + Properties result = (Properties)System.getProperties().clone(); + for (String each : new THashSet((Set)result.keySet())) { + if (each.startsWith("idea.")) { + result.remove(each); + } + } + return result; + } + + public static Properties getEnvProperties() { + Properties reuslt = new Properties(); + for (Map.Entry each : System.getenv().entrySet()) { + if (isMagicalProperty(each.getKey())) continue; + reuslt.put(each.getKey(), each.getValue()); + } + return reuslt; + } + + private static boolean isMagicalProperty(String key) { + return key.startsWith("="); + } + + public static File getPluginSystemDir(String folder) { + // PathManager.getSystemPath() may return relative path + return new File(PathManager.getSystemPath(), "Maven" + "/" + folder).getAbsoluteFile(); + } + + public static VirtualFile findProfilesXmlFile(VirtualFile pomFile) { + return pomFile.getParent().findChild(MavenConstants.PROFILES_XML); + } + + public static File getProfilesXmlIoFile(VirtualFile pomFile) { + return new File(pomFile.getParent().getPath(), MavenConstants.PROFILES_XML); + } + + public static List collectFirsts(List> pairs) { + List result = new ArrayList(pairs.size()); + for (Pair each : pairs) { + result.add(each.first); + } + return result; + } + + public static List collectSeconds(List> pairs) { + List result = new ArrayList(pairs.size()); + for (Pair each : pairs) { + result.add(each.second); + } + return result; + } + + public static List collectPaths(List files) { + return ContainerUtil.map(files, new Function() { + public String fun(VirtualFile file) { + return file.getPath(); + } + }); + } + + public static List collectFiles(Collection projects) { + return ContainerUtil.map(projects, new Function() { + public VirtualFile fun(MavenProject project) { + return project.getFile(); + } + }); + } + + public static boolean equalAsSets(final Collection collection1, final Collection collection2) { + return toSet(collection1).equals(toSet(collection2)); + } + + private static Collection toSet(final Collection collection) { + return (collection instanceof Set ? collection : new THashSet(collection)); + } + + public static List> mapToList(Map map) { + return ContainerUtil.map2List(map.entrySet(), new Function, Pair>() { + public Pair fun(Map.Entry tuEntry) { + return Pair.create(tuEntry.getKey(), tuEntry.getValue()); + } + }); + } + + public static String formatHtmlImage(URL url) { + return " "; + } + + public static void runOrApplyMavenProjectFileTemplate(Project project, + VirtualFile file, + MavenId projectId, + boolean interactive) throws IOException { + runOrApplyMavenProjectFileTemplate(project, file, projectId, null, null, interactive); + } + + public static void runOrApplyMavenProjectFileTemplate(Project project, + VirtualFile file, + MavenId projectId, + MavenId parentId, + VirtualFile parentFile, + boolean interactive) throws IOException { + Properties properties = new Properties(); + Properties conditions = new Properties(); + properties.setProperty("GROUP_ID", projectId.getGroupId()); + properties.setProperty("ARTIFACT_ID", projectId.getArtifactId()); + properties.setProperty("VERSION", projectId.getVersion()); + if (parentId != null) { + conditions.setProperty("HAS_PARENT", "true"); + properties.setProperty("PARENT_GROUP_ID", parentId.getGroupId()); + properties.setProperty("PARENT_ARTIFACT_ID", parentId.getArtifactId()); + properties.setProperty("PARENT_VERSION", parentId.getVersion()); + + if (parentFile != null) { + VirtualFile modulePath = file.getParent(); + VirtualFile parentModulePath = parentFile.getParent(); + + if (!Comparing.equal(modulePath.getParent(), parentModulePath)) { + String relativePath = VfsUtil.getPath(file, parentModulePath, '/'); + if (relativePath != null) { + if (relativePath.endsWith("/")) relativePath = relativePath.substring(0, relativePath.length() - 1); + + conditions.setProperty("HAS_RELATIVE_PATH", "true"); + properties.setProperty("PARENT_RELATIVE_PATH", relativePath); + } + } + } + } + runOrApplyFileTemplate(project, file, MavenFileTemplateGroupFactory.MAVEN_PROJECT_XML_TEMPLATE, properties, conditions, interactive); + } + + public static void runFileTemplate(Project project, + VirtualFile file, + String templateName) throws IOException { + runOrApplyFileTemplate(project, file, templateName, new Properties(), new Properties(), true); + } + + private static void runOrApplyFileTemplate(Project project, + VirtualFile file, + String templateName, + Properties properties, + Properties conditions, + boolean interactive) throws IOException { + FileTemplateManager manager = FileTemplateManager.getInstance(); + FileTemplate fileTemplate = manager.getJ2eeTemplate(templateName); + Properties allProperties = manager.getDefaultProperties(project); + if (!interactive) { + allProperties.putAll(properties); + } + allProperties.putAll(conditions); + String text = fileTemplate.getText(allProperties); + Pattern pattern = Pattern.compile("\\$\\{(.*)\\}"); + Matcher matcher = pattern.matcher(text); + StringBuffer builder = new StringBuffer(); + while (matcher.find()) { + matcher.appendReplacement(builder, "\\$" + matcher.group(1).toUpperCase() + "\\$"); + } + matcher.appendTail(builder); + text = builder.toString(); + + TemplateImpl template = (TemplateImpl)TemplateManager.getInstance(project).createTemplate("", "", text); + for (int i = 0; i < template.getSegmentsCount(); i++) { + if (i == template.getEndSegmentNumber()) continue; + String name = template.getSegmentName(i); + String value = "\"" + properties.getProperty(name, "") + "\""; + template.addVariable(name, value, value, true); + } + + if (interactive) { + OpenFileDescriptor descriptor = new OpenFileDescriptor(project, file); + Editor editor = FileEditorManager.getInstance(project).openTextEditor(descriptor, true); + editor.getDocument().setText(""); + TemplateManager.getInstance(project).startTemplate(editor, template); + } + else { + VfsUtil.saveText(file, template.getTemplateText()); + } + } + + public static > T collectPattern(String text, T result) { + String antPattern = FileUtil.convertAntToRegexp(text.trim()); + try { + result.add(Pattern.compile(antPattern)); + } + catch (PatternSyntaxException ignore) { + } + return result; + } + + public static boolean isIncluded(String relativeName, List includes, List excludes) { + boolean result = false; + for (Pattern each : includes) { + if (each.matcher(relativeName).matches()) { + result = true; + break; + } + } + if (!result) return false; + for (Pattern each : excludes) { + if (each.matcher(relativeName).matches()) return false; + } + return true; + } + + public static void run(Project project, String title, final MavenTask task) throws MavenProcessCanceledException { + final Exception[] canceledEx = new Exception[1]; + final RuntimeException[] runtimeEx = new RuntimeException[1]; + final Error[] errorEx = new Error[1]; + + ProgressManager.getInstance().run(new Task.Modal(project, title, true) { + public void run(@NotNull ProgressIndicator i) { + try { + task.run(new MavenProgressIndicator(i)); + } + catch (MavenProcessCanceledException e) { + canceledEx[0] = e; + } + catch (ProcessCanceledException e) { + canceledEx[0] = e; + } + catch (RuntimeException e) { + runtimeEx[0] = e; + } + catch (Error e) { + errorEx[0] = e; + } + } + }); + if (canceledEx[0] instanceof MavenProcessCanceledException) throw (MavenProcessCanceledException)canceledEx[0]; + if (canceledEx[0] instanceof ProcessCanceledException) throw new MavenProcessCanceledException(); + + if (runtimeEx[0] != null) throw runtimeEx[0]; + if (errorEx[0] != null) throw errorEx[0]; + } + + public static MavenTaskHandler runInBackground(final Project project, + final String title, + final boolean cancellable, + final MavenTask task) { + final MavenProgressIndicator indicator = new MavenProgressIndicator(); + + Runnable runnable = new Runnable() { + public void run() { + try { + task.run(indicator); + } + catch (MavenProcessCanceledException ignore) { + indicator.cancel(); + } + catch (ProcessCanceledException ignore) { + indicator.cancel(); + } + } + }; + + if (isNoBackgroundMode()) { + runnable.run(); + return new MavenTaskHandler() { + public void waitFor() { + } + }; + } + else { + final Future future = ApplicationManager.getApplication().executeOnPooledThread(runnable); + final MavenTaskHandler handler = new MavenTaskHandler() { + public void waitFor() { + try { + future.get(); + } + catch (InterruptedException e) { + MavenLog.LOG.error(e); + } + catch (ExecutionException e) { + MavenLog.LOG.error(e); + } + } + }; + invokeLater(project, new Runnable() { + public void run() { + if (future.isDone()) return; + new Task.Backgroundable(project, title, cancellable) { + public void run(@NotNull ProgressIndicator i) { + indicator.setIndicator(i); + handler.waitFor(); + } + }.queue(); + } + }); + return handler; + } + } + + @Nullable + public static File resolveMavenHomeDirectory(@Nullable String overrideMavenHome) { + if (!isEmptyOrSpaces(overrideMavenHome)) { + return new File(overrideMavenHome); + } + + String m2home = System.getenv(ENV_M2_HOME); + if (!isEmptyOrSpaces(m2home)) { + final File homeFromEnv = new File(m2home); + if (isValidMavenHome(homeFromEnv)) { + return homeFromEnv; + } + } + + String userHome = SystemProperties.getUserHome(); + if (!isEmptyOrSpaces(userHome)) { + final File underUserHome = new File(userHome, M2_DIR); + if (isValidMavenHome(underUserHome)) { + return underUserHome; + } + } + + if (SystemInfo.isMac) { + File home = fromBrew(); + if (home != null) { + return home; + } + + if ((home = fromMacSystemJavaTools()) != null) { + return home; + } + } + else if (SystemInfo.isLinux) { + File home = new File("/usr/share/maven2"); + if (isValidMavenHome(home)) { + return home; + } + } + + return null; + } + + @Nullable + private static File fromMacSystemJavaTools() { + final File symlinkDir = new File("/usr/share/maven"); + if (isValidMavenHome(symlinkDir)) { + return symlinkDir; + } + + // well, try to search + final File dir = new File("/usr/share/java"); + final String[] list = dir.list(); + if (list == null || list.length == 0) { + return null; + } + + String home = null; + final String prefix = "maven-"; + final int versionIndex = prefix.length(); + for (String path : list) { + if (path.startsWith(prefix) && + (home == null || StringUtil.compareVersionNumbers(path.substring(versionIndex), home.substring(versionIndex)) > 0)) { + home = path; + } + } + + if (home != null) { + File file = new File(dir, home); + if (isValidMavenHome(file)) { + return file; + } + } + + return null; + } + + @Nullable + private static File fromBrew() { + final File brewDir = new File("/usr/local/Cellar/maven"); + final String[] list = brewDir.list(); + if (list == null || list.length == 0) { + return null; + } + + if (list.length > 1) { + Arrays.sort(list, new Comparator() { + @Override + public int compare(String o1, String o2) { + return StringUtil.compareVersionNumbers(o2, o1); + } + }); + } + + final File file = new File(brewDir, list[0] + "/libexec"); + return isValidMavenHome(file) ? file : null; + } + + public static boolean isEmptyOrSpaces(@Nullable String str) { + return str == null || str.length() == 0 || str.trim().length() == 0; + } + + public static boolean isValidMavenHome(File home) { + return getMavenConfFile(home).exists(); + } + + public static File getMavenConfFile(File mavenHome) { + return new File(new File(mavenHome, BIN_DIR), M2_CONF_FILE); + } + + @Nullable + public static File resolveGlobalSettingsFile(@Nullable String overriddenMavenHome) { + File directory = resolveMavenHomeDirectory(overriddenMavenHome); + if (directory == null) return null; + + return new File(new File(directory, CONF_DIR), SETTINGS_XML); + } + + @NotNull + public static File resolveUserSettingsFile(@Nullable String overriddenUserSettingsFile) { + if (!isEmptyOrSpaces(overriddenUserSettingsFile)) return new File(overriddenUserSettingsFile); + return new File(resolveM2Dir(), SETTINGS_XML); + } + + @NotNull + public static File resolveM2Dir() { + return new File(SystemProperties.getUserHome(), DOT_M2_DIR); + } + + @NotNull + public static File resolveLocalRepository(@Nullable String overriddenLocalRepository, + @Nullable String overriddenMavenHome, + @Nullable String overriddenUserSettingsFile) { + File result = null; + if (!isEmptyOrSpaces(overriddenLocalRepository)) result = new File(overriddenLocalRepository); + if (result == null) { + result = doResolveLocalRepository(resolveUserSettingsFile(overriddenUserSettingsFile), + resolveGlobalSettingsFile(overriddenMavenHome)); + } + try { + return result.getCanonicalFile(); + } + catch (IOException e) { + return result; + } + } + + @NotNull + public static File doResolveLocalRepository(@Nullable File userSettingsFile, @Nullable File globalSettingsFile) { + if (userSettingsFile != null) { + final String fromUserSettings = getRepositoryFromSettings(userSettingsFile); + if (!StringUtil.isEmpty(fromUserSettings)) { + return new File(fromUserSettings); + } + } + + if (globalSettingsFile != null) { + final String fromGlobalSettings = getRepositoryFromSettings(globalSettingsFile); + if (!StringUtil.isEmpty(fromGlobalSettings)) { + return new File(fromGlobalSettings); + } + } + + return new File(resolveM2Dir(), REPOSITORY_DIR); + } + + @Nullable + public static String getRepositoryFromSettings(final File file) { + try { + byte[] bytes = FileUtil.loadFileBytes(file); + return expandProperties(MavenJDOMUtil.findChildValueByPath(MavenJDOMUtil.read(bytes, null), "localRepository", null)); + } + catch (IOException e) { + return null; + } + } + + public static String expandProperties(String text) { + if (StringUtil.isEmptyOrSpaces(text)) return text; + Properties props = MavenServerUtil.collectSystemProperties(); + for (Map.Entry each : props.entrySet()) { + Object val = each.getValue(); + text = text.replace("${" + each.getKey() + "}", val instanceof CharSequence ? (CharSequence)val : val.toString()); + } + return text; + } + + @NotNull + public static VirtualFile resolveSuperPomFile(@Nullable File mavenHome) { + VirtualFile result = null; + if (mavenHome != null) { + result = doResolveSuperPomFile(new File(mavenHome, LIB_DIR)); + } + if (result == null) { + result = doResolveSuperPomFile(MavenServerManager.collectClassPathAndLibsFolder().second); + } + return result; + } + + @Nullable + public static VirtualFile doResolveSuperPomFile(@NotNull File mavenHome) { + File[] files = mavenHome.listFiles(); + if (files == null) return null; + + for (File library : files) { + + for (Pair path : SUPER_POM_PATHS) { + if (path.first.matcher(library.getName()).matches()) { + VirtualFile libraryVirtualFile = LocalFileSystem.getInstance().findFileByIoFile(library); + if (libraryVirtualFile == null) continue; + + VirtualFile root = JarFileSystem.getInstance().getJarRootForLocalFile(libraryVirtualFile); + if (root == null) continue; + + VirtualFile pomFile = root.findFileByRelativePath(path.second); + if (pomFile != null) { + return pomFile; + } + } + } + } + + return null; + } + + public interface MavenTaskHandler { + void waitFor(); + } +} diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java index 7ddb4d84ba25..5da5eaa7c22b 100644 --- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java +++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java @@ -248,7 +248,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit @Override public void fileDeleted(VirtualFileEvent event) { for (PropertiesFile file : myEditors.keySet()) { - if (file.getVirtualFile() == event.getFile()) { + if (Comparing.equal(file.getVirtualFile(), event.getFile())) { recreateEditorsPanel(); return; } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListener.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListener.java index b814fad64a2c..f6b94374e688 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListener.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListener.java @@ -1,974 +1,975 @@ -/* - * Copyright 2000-2009 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.idea.svn; - -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.command.CommandAdapter; -import com.intellij.openapi.command.CommandEvent; -import com.intellij.openapi.command.undo.UndoManager; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.progress.ProgressManager; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectManager; -import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.vcs.*; -import com.intellij.openapi.vcs.actions.VcsContextFactory; -import com.intellij.openapi.vcs.changes.ChangeListManager; -import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager; -import com.intellij.openapi.vfs.LocalFileOperationsHandler; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.newvfs.RefreshQueue; -import com.intellij.openapi.vfs.newvfs.RefreshSession; -import com.intellij.util.ThrowableConsumer; -import com.intellij.util.containers.MultiMap; -import com.intellij.vcsUtil.ActionWithTempFile; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.tmatesoft.svn.core.SVNErrorCode; -import org.tmatesoft.svn.core.SVNException; -import org.tmatesoft.svn.core.SVNNodeKind; -import org.tmatesoft.svn.core.internal.wc.SVNFileUtil; -import org.tmatesoft.svn.core.wc.*; - -import java.io.File; -import java.io.IOException; -import java.util.*; - -public class SvnFileSystemListener extends CommandAdapter implements LocalFileOperationsHandler { - private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.SvnFileSystemListener"); - private final LocalFileSystem myLfs; - - private static class AddedFileInfo { - private final VirtualFile myDir; - private final String myName; - @Nullable private final File myCopyFrom; - private final boolean myRecursive; - - public AddedFileInfo(final VirtualFile dir, final String name, @Nullable final File copyFrom, boolean recursive) { - myDir = dir; - myName = name; - myCopyFrom = copyFrom; - myRecursive = recursive; - } - } - - private static class MovedFileInfo { - private final Project myProject; - private final File mySrc; - private final File myDst; - - private MovedFileInfo(final Project project, final File src, final File dst) { - myProject = project; - mySrc = src; - myDst = dst; - } - } - - private final MultiMap myAddedFiles = new MultiMap(); - private final MultiMap myDeletedFiles = new MultiMap(); - private final List myMovedFiles = new ArrayList(); - private final Map> myMoveExceptions = new HashMap>(); - private final List myFilesToRefresh = new ArrayList(); - @Nullable private File myStorageForUndo; - private final List> myUndoStorageContents = new ArrayList>(); - private boolean myUndoingMove = false; - - public SvnFileSystemListener() { - myLfs = LocalFileSystem.getInstance(); - } - - private void addToMoveExceptions(final Project project, final SVNException e) { - List exceptionList = myMoveExceptions.get(project); - if (exceptionList == null) { - exceptionList = new ArrayList(); - myMoveExceptions.put(project, exceptionList); - } - VcsException vcsException; - if (SVNErrorCode.ENTRY_EXISTS.equals(e.getErrorMessage().getErrorCode())) { - vcsException = new VcsException(Arrays.asList("Target of move operation is already under version control.", - "Subversion move had not been performed. ", e.getMessage())); - } else { - vcsException = new VcsException(e); - } - exceptionList.add(vcsException); - } - - @Nullable - public File copy(final VirtualFile file, final VirtualFile toDir, final String copyName) throws IOException { - SvnVcs vcs = getVCS(toDir); - if (vcs == null) { - vcs = getVCS(file); - } - if (vcs == null) { - return null; - } - - File srcFile = new File(file.getPath()); - File destFile = new File(new File(toDir.getPath()), copyName); - final boolean dstDirUnderControl = SvnUtil.isSvnVersioned(vcs.getProject(), destFile.getParentFile()); - if (! dstDirUnderControl && !isPendingAdd(vcs.getProject(), toDir)) { - return null; - } - - if (! SvnUtil.isSvnVersioned(vcs.getProject(), srcFile.getParentFile())) { - myAddedFiles.putValue(vcs.getProject(), new AddedFileInfo(toDir, copyName, null, false)); - return null; - } - - final SVNStatus fileStatus = getFileStatus(vcs, srcFile); - if (fileStatus != null && SvnVcs.svnStatusIs(fileStatus, SVNStatusType.STATUS_ADDED)) { - myAddedFiles.putValue(vcs.getProject(), new AddedFileInfo(toDir, copyName, null, false)); - return null; - } - - if (sameRoot(vcs, file.getParent(), toDir)) { - myAddedFiles.putValue(vcs.getProject(), new AddedFileInfo(toDir, copyName, srcFile, false)); - return null; - } - - myAddedFiles.putValue(vcs.getProject(), new AddedFileInfo(toDir, copyName, null, false)); - return null; - } - - private boolean sameRoot(final SvnVcs vcs, final VirtualFile srcDir, final VirtualFile dstDir) { - final UUIDHelper helper = new UUIDHelper(vcs); - final String srcUUID = helper.getRepositoryUUID(vcs.getProject(), srcDir); - final String dstUUID = helper.getRepositoryUUID(vcs.getProject(), dstDir); - - return srcUUID != null && dstUUID != null && srcUUID.equals(dstUUID); - } - - private class UUIDHelper { - private final SVNWCClient myWcClient; - - private UUIDHelper(final SvnVcs vcs) { - myWcClient = vcs.createWCClient(); - } - - /** - * passed dir must be under VC control (it is assumed) - */ - @Nullable - public String getRepositoryUUID(final Project project, final VirtualFile dir) { - try { - final SVNInfo info1 = new RepeatSvnActionThroughBusy() { - @Override - protected void executeImpl() throws SVNException { - myT = myWcClient.doInfo(new File(dir.getPath()), SVNRevision.UNDEFINED); - } - }.compute(); - if (info1 == null || info1.getRepositoryUUID() == null) { - // go deeper if current parent was added (if parent was added, it theoretically could NOT know its repo UUID) - final VirtualFile parent = dir.getParent(); - if (parent == null) { - return null; - } - if (isPendingAdd(project, parent)) { - return getRepositoryUUID(project, parent); - } - } else { - return info1.getRepositoryUUID(); - } - } catch (SVNException e) { - // go to return default - } - return null; - } - } - - public boolean move(VirtualFile file, VirtualFile toDir) throws IOException { - File srcFile = getIOFile(file); - File dstFile = new File(getIOFile(toDir), file.getName()); - - final SvnVcs vcs = getVCS(toDir); - final SvnVcs sourceVcs = getVCS(file); - if (vcs == null && sourceVcs == null) return false; - - if (vcs == null) { - return false; - } - if (sourceVcs == null) { - return createItem(toDir, file.getName(), file.isDirectory(), true); - } - - if (isPendingAdd(vcs.getProject(), toDir)) { - - myMovedFiles.add(new MovedFileInfo(sourceVcs.getProject(), srcFile, dstFile)); - return true; - } - else { - final VirtualFile oldParent = file.getParent(); - myFilesToRefresh.add(oldParent); - myFilesToRefresh.add(toDir); - return doMove(sourceVcs, srcFile, dstFile); - } - } - - public boolean rename(VirtualFile file, String newName) throws IOException { - File srcFile = getIOFile(file); - File dstFile = new File(srcFile.getParentFile(), newName); - SvnVcs vcs = getVCS(file); - if (vcs != null) { - myFilesToRefresh.add(file.getParent()); - return doMove(vcs, srcFile, dstFile); - } - return false; - } - - private boolean doMove(@NotNull SvnVcs vcs, final File src, final File dst) { - long srcTime = src.lastModified(); - try { - final boolean isUndo = isUndo(vcs); - final String list = isUndo ? null : SvnChangelistListener.getCurrentMapping(vcs.getProject(), src); - - final boolean is17 = SvnUtil.is17CopyPart(src); - if (is17) { - if (for17move(vcs, src, dst, isUndo)) return false; - } else { - if (for16move(vcs, src, dst, isUndo)) return false; - } - - if (! isUndo && list != null) { - SvnChangelistListener.putUnderList(vcs.getProject(), list, dst); - } - dst.setLastModified(srcTime); - } - catch (SVNException e) { - addToMoveExceptions(vcs.getProject(), e); - return false; - } - return true; - } - - private boolean for17move(SvnVcs vcs, final File src, final File dst, boolean undo) throws SVNException { - if (undo) { - final SVNWCClient wcClient = vcs.createWCClient(); - myUndoingMove = true; - new RepeatSvnActionThroughBusy() { - @Override - protected void executeImpl() throws SVNException { - wcClient.doRevert(dst, true); - } - }.execute(); - new RepeatSvnActionThroughBusy() { - @Override - protected void executeImpl() throws SVNException { - wcClient.doRevert(src, true); - } - }.execute(); - restoreFromUndoStorage(dst); - } else { - if (doUsualMove(vcs, src)) return true; - final SVNCopyClient copyClient = vcs.createCopyClient(); - final SVNCopySource svnCopySource = new SVNCopySource(SVNRevision.UNDEFINED, SVNRevision.WORKING, src); - new RepeatSvnActionThroughBusy() { - @Override - protected void executeImpl() throws SVNException { - copyClient.doCopy(new SVNCopySource[]{svnCopySource}, dst, true, false, true); - } - }.execute(); - } - return false; - } - - private boolean doUsualMove(SvnVcs vcs, File src) { - // if src is not under version control, do usual move. - SVNStatus srcStatus = getFileStatus(vcs, src); - if (srcStatus == null || SvnVcs.svnStatusIsUnversioned(srcStatus) || - SvnVcs.svnStatusIs(srcStatus, SVNStatusType.STATUS_OBSTRUCTED) || - SvnVcs.svnStatusIs(srcStatus, SVNStatusType.STATUS_MISSING) || - SvnVcs.svnStatusIs(srcStatus, SVNStatusType.STATUS_EXTERNAL)) { - return true; - } - return false; - } - - private boolean for16move(SvnVcs vcs, final File src, final File dst, boolean undo) throws SVNException { - final SVNMoveClient mover = vcs.createMoveClient(); - if (undo) { - myUndoingMove = true; - restoreFromUndoStorage(dst); - new RepeatSvnActionThroughBusy() { - @Override - protected void executeImpl() throws SVNException { - mover.undoMove(src, dst); - } - }.execute(); - } - else { - // if src is not under version control, do usual move. - if (doUsualMove(vcs, src)) return true; - new RepeatSvnActionThroughBusy() { - @Override - protected void executeImpl() throws SVNException { - mover.doMove(src, dst); - } - }.execute(); - } - return false; - } - - private void restoreFromUndoStorage(final File dst) { - String normPath = FileUtil.toSystemIndependentName(dst.getPath()); - for (Iterator> it = myUndoStorageContents.iterator(); it.hasNext();) { - Pair e = it.next(); - final String p = FileUtil.toSystemIndependentName(e.first.getPath()); - if (p.startsWith(normPath)) { - try { - FileUtil.rename(e.second, e.first); - } - catch (IOException ex) { - LOG.error(ex); - FileUtil.asyncDelete(e.second); - } - it.remove(); - } - } - if (myStorageForUndo != null) { - final File[] files = myStorageForUndo.listFiles(); - if (files == null || files.length == 0) { - FileUtil.asyncDelete(myStorageForUndo); - myStorageForUndo = null; - } - } - } - - - public boolean createFile(VirtualFile dir, String name) throws IOException { - return createItem(dir, name, false, false); - } - - public boolean createDirectory(VirtualFile dir, String name) throws IOException { - return createItem(dir, name, true, false); - } - - /** - * delete file or directory (both 'undo' and 'do' modes) - * unversioned: do nothing, return false - * obstructed: do nothing, return false - * external or wc root: do nothing, return false - * missing: do nothing, return false - *

    - * versioned: schedule for deletion, return true - * added: schedule for deletion (make unversioned), return true - * copied, but not scheduled: schedule for deletion, return true - * replaced: schedule for deletion, return true - *

    - * deleted: do nothing, return true (strange) - */ - public boolean delete(VirtualFile file) throws IOException { - SvnVcs vcs = getVCS(file); - if (vcs != null && SvnUtil.isAdminDirectory(file)) { - return true; - } - if (vcs == null) return false; - final File ioFile = getIOFile(file); - if (! SvnUtil.isSvnVersioned(vcs.getProject(), ioFile.getParentFile())) { - return false; - } - try { - if (SVNWCUtil.isWorkingCopyRoot(ioFile)) { - return false; - } - } catch (SVNException e) { - // - } - - SVNStatus status = getFileStatus(ioFile); - - if (status == null || - SvnVcs.svnStatusIsUnversioned(status) || - SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_OBSTRUCTED) || - SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_MISSING) || - SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_EXTERNAL) || - SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_IGNORED)) { - return false; - } else if (SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_DELETED)) { - if (isUndo(vcs)) { - moveToUndoStorage(file); - } - return true; - } - else { - if (vcs != null) { - if (isAboveSourceOfCopyOrMove(vcs.getProject(), ioFile)) { - myDeletedFiles.putValue(vcs.getProject(), ioFile); - return true; - } - if (SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_ADDED)) { - try { - final SVNWCClient wcClient = vcs.createWCClient(); - new RepeatSvnActionThroughBusy() { - @Override - protected void executeImpl() throws SVNException { - wcClient.doRevert(ioFile, false); - } - }.execute(); - } - catch (SVNException e) { - // ignore - } - } - else { - myDeletedFiles.putValue(vcs.getProject(), ioFile); - // packages deleted from disk should not be deleted from svn (IDEADEV-16066) - if (file.isDirectory() || isUndo(vcs)) return true; - } - } - return false; - } - } - - private boolean isAboveSourceOfCopyOrMove(final Project p, File ioFile) { - for (MovedFileInfo file : myMovedFiles) { - if (FileUtil.isAncestor(ioFile, file.mySrc, false)) return true; - } - for (AddedFileInfo info : myAddedFiles.get(p)) { - if (info.myCopyFrom != null && FileUtil.isAncestor(ioFile, info.myCopyFrom, false)) return true; - } - return false; - } - - private void moveToUndoStorage(final VirtualFile file) { - if (myStorageForUndo == null) { - try { - myStorageForUndo = FileUtil.createTempDirectory("svnUndoStorage", ""); - } - catch (IOException e) { - LOG.error(e); - return; - } - } - final File tmpFile = FileUtil.findSequentNonexistentFile(myStorageForUndo, "tmp", ""); - myUndoStorageContents.add(0, new Pair(new File(file.getPath()), tmpFile)); - new File(file.getPath()).renameTo(tmpFile); - } - - /** - * add file or directory: - *

    - * parent directory is: - * unversioned: do nothing, return false - * versioned: - * entry is: - * null: create entry, schedule for addition - * missing: do nothing, return false - * deleted, 'do' mode: try to create entry and it schedule for addition if kind is the same, otherwise do nothing, return false. - * deleted: 'undo' mode: try to revert non-recursively, if kind is the same, otherwise do nothing, return false. - * anything else: return false. - */ - private boolean createItem(VirtualFile dir, String name, boolean directory, final boolean recursive) { - SvnVcs vcs = getVCS(dir); - if (vcs == null) { - return false; - } - if (isUndo(vcs) && SvnUtil.isAdminDirectory(dir, name)) { - return false; - } - File ioDir = getIOFile(dir); - boolean pendingAdd = isPendingAdd(vcs.getProject(), dir); - if (! SvnUtil.isSvnVersioned(vcs.getProject(), ioDir) && ! pendingAdd) { - return false; - } - final SVNWCClient wcClient = vcs.createWCClient(); - final File targetFile = new File(ioDir, name); - SVNStatus status = getFileStatus(vcs, targetFile); - - if (status == null || status.getContentsStatus() == SVNStatusType.STATUS_NONE || - status.getContentsStatus() == SVNStatusType.STATUS_UNVERSIONED) { - myAddedFiles.putValue(vcs.getProject(), new AddedFileInfo(dir, name, null, recursive)); - return false; - } - else if (SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_MISSING)) { - return false; - } - else if (SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_DELETED)) { - SVNNodeKind kind = status.getKind(); - // kind differs. - if (directory && kind != SVNNodeKind.DIR || !directory && kind != SVNNodeKind.FILE) { - return false; - } - try { - if (isUndo(vcs)) { - new RepeatSvnActionThroughBusy() { - @Override - protected void executeImpl() throws SVNException { - wcClient.doRevert(targetFile, false); - } - }.execute(); - return true; - } - myAddedFiles.putValue(vcs.getProject(), new AddedFileInfo(dir, name, null, recursive)); - return false; - } - catch (SVNException e) { - SVNFileUtil.deleteAll(targetFile, true); - return false; - } - } - return false; - } - - private boolean isPendingAdd(final Project project, final VirtualFile dir) { - final Collection addedFileInfos = myAddedFiles.get(project); - for(AddedFileInfo i: addedFileInfos) { - if (i.myDir == dir.getParent() && i.myName.equals(dir.getName())) { - return true; - } - } - return false; - } - - public void commandStarted(CommandEvent event) { - myUndoingMove = false; - final Project project = event.getProject(); - if (project == null) return; - commandStarted(project); - } - - void commandStarted(final Project project) { - myUndoingMove = false; - myMoveExceptions.remove(project); - } - - public void commandFinished(CommandEvent event) { - final Project project = event.getProject(); - if (project == null) return; - commandFinished(project); - } - - void commandFinished(final Project project) { - checkOverwrites(project); - if (myAddedFiles.containsKey(project)) { - processAddedFiles(project); - } - processMovedFiles(project); - if (myDeletedFiles.containsKey(project)) { - processDeletedFiles(project); - } - - final List exceptionList = myMoveExceptions.get(project); - if (exceptionList != null && ! exceptionList.isEmpty()) { - AbstractVcsHelper.getInstance(project).showErrors(exceptionList, SvnBundle.message("move.files.errors.title")); - } - - if (!myFilesToRefresh.isEmpty()) { - refreshFiles(project); - } - } - - private void checkOverwrites(final Project project) { - final Collection addedFileInfos = myAddedFiles.get(project); - final Collection deletedFiles = myDeletedFiles.get(project); - if (addedFileInfos.isEmpty() || deletedFiles.isEmpty()) return; - final Iterator iterator = addedFileInfos.iterator(); - while (iterator.hasNext()) { - AddedFileInfo addedFileInfo = iterator.next(); - final File ioFile = new File(addedFileInfo.myDir.getPath(), addedFileInfo.myName); - if (deletedFiles.remove(ioFile)) { - iterator.remove(); - } - } - } - - private void refreshFiles(final Project project) { - final List toRefreshFiles = new ArrayList(); - final List toRefreshDirs = new ArrayList(); - for (VirtualFile file : myFilesToRefresh) { - if (file == null) continue; - if (file.isDirectory()) { - toRefreshDirs.add(file); - } else { - toRefreshFiles.add(file); - } - } - // if refresh asynchronously, local changes would also be notified that they are dirty asynchronously, - // and commit could be executed while not all changes are visible - final RefreshSession session = RefreshQueue.getInstance().createSession(true, true, new Runnable() { - public void run() { - if (project.isDisposed()) return; - filterOutInvalid(toRefreshFiles); - filterOutInvalid(toRefreshDirs); - - final VcsDirtyScopeManager vcsDirtyScopeManager = VcsDirtyScopeManager.getInstance(project); - vcsDirtyScopeManager.filesDirty(toRefreshFiles, toRefreshDirs); - } - }); - filterOutInvalid(myFilesToRefresh); - session.addAllFiles(myFilesToRefresh); - session.launch(); - myFilesToRefresh.clear(); - } - - private static void filterOutInvalid(final Collection files) { - for (Iterator iterator = files.iterator(); iterator.hasNext();) { - final VirtualFile file = iterator.next(); - if (! file.isValid() || ! file.exists()) { - LOG.info("Refresh root is not valid: " + file.getPath()); - iterator.remove(); - } - } - } - - private void processAddedFiles(Project project) { - SvnVcs vcs = SvnVcs.getInstance(project); - List addedVFiles = new ArrayList(); - Map copyFromMap = new HashMap(); - final Set recursiveItems = new HashSet(); - fillAddedFiles(project, vcs, addedVFiles, copyFromMap, recursiveItems); - if (addedVFiles.isEmpty()) return; - final VcsShowConfirmationOption.Value value = vcs.getAddConfirmation().getValue(); - if (value != VcsShowConfirmationOption.Value.DO_NOTHING_SILENTLY) { - final AbstractVcsHelper vcsHelper = AbstractVcsHelper.getInstance(project); - final Collection filesToProcess = promptAboutAddition(vcs, addedVFiles, value, vcsHelper); - if (filesToProcess != null && !filesToProcess.isEmpty()) { - final List exceptions = new ArrayList(); - runInBackground(project, "Adding files to Subversion", - createAdditionRunnable(project, vcs, copyFromMap, filesToProcess, exceptions)); - if (!exceptions.isEmpty()) { - vcsHelper.showErrors(exceptions, SvnBundle.message("add.files.errors.title")); - } - } - } - } - - private void runInBackground(final Project project, final String name, final Runnable runnable) { - if (ApplicationManager.getApplication().isDispatchThread()) { - ProgressManager.getInstance().runProcessWithProgressSynchronously(runnable, name, false, project); - } else { - runnable.run(); - } - } - - private Runnable createAdditionRunnable(final Project project, - final SvnVcs vcs, - final Map copyFromMap, - final Collection filesToProcess, - final List exceptions) { - return new Runnable() { - @Override - public void run() { - final SVNWCClient wcClient = vcs.createWCClient(); - final SVNCopyClient copyClient = vcs.createCopyClient(); - for(VirtualFile file: filesToProcess) { - final File ioFile = new File(file.getPath()); - try { - final File copyFrom = copyFromMap.get(file); - if (copyFrom != null) { - try { - new ActionWithTempFile(ioFile) { - protected void executeInternal() throws VcsException { - try { - // not recursive - final SVNCopySource[] copySource = {new SVNCopySource(SVNRevision.WORKING, SVNRevision.WORKING, copyFrom)}; - new RepeatSvnActionThroughBusy() { - @Override - protected void executeImpl() throws SVNException { - copyClient.doCopy(copySource, ioFile, false, true, true); - } - }.execute(); - } - catch (SVNException e) { - throw new VcsException(e); - } - } - }.execute(); - } - catch (VcsException e) { - exceptions.add(e); - } - } - else { - new RepeatSvnActionThroughBusy() { - @Override - protected void executeImpl() throws SVNException { - wcClient.doAdd(ioFile, true, false, false, true); - } - }.execute(); - } - VcsDirtyScopeManager.getInstance(project).fileDirty(file); - } - catch (SVNException e) { - exceptions.add(new VcsException(e)); - } - } - } - }; - } - - private Collection promptAboutAddition(SvnVcs vcs, - List addedVFiles, - VcsShowConfirmationOption.Value value, - AbstractVcsHelper vcsHelper) { - Collection filesToProcess; - if (value == VcsShowConfirmationOption.Value.DO_ACTION_SILENTLY) { - filesToProcess = addedVFiles; - } - else { - final String singleFilePrompt; - if (addedVFiles.size() == 1 && addedVFiles.get(0).isDirectory()) { - singleFilePrompt = SvnBundle.getString("confirmation.text.add.dir"); - } - else { - singleFilePrompt = SvnBundle.getString("confirmation.text.add.file"); - } - filesToProcess = vcsHelper.selectFilesToProcess(addedVFiles, SvnBundle.message("confirmation.title.add.multiple.files"), - null, - SvnBundle.message("confirmation.title.add.file"), singleFilePrompt, - vcs.getAddConfirmation()); - } - return filesToProcess; - } - - private void fillAddedFiles(Project project, - SvnVcs vcs, - List addedVFiles, - Map copyFromMap, - Set recursiveItems) { - final Collection addedFileInfos = myAddedFiles.remove(project); - final ChangeListManager changeListManager = ChangeListManager.getInstance(project); - - for (AddedFileInfo addedFileInfo : addedFileInfos) { - final File ioFile = new File(getIOFile(addedFileInfo.myDir), addedFileInfo.myName); - VirtualFile addedFile = addedFileInfo.myDir.findChild(addedFileInfo.myName); - if (addedFile == null) { - addedFile = myLfs.refreshAndFindFileByIoFile(ioFile); - } - if (addedFile != null) { - final SVNStatus fileStatus = getFileStatus(vcs, ioFile); - if (fileStatus == null || ! SvnVcs.svnStatusIs(fileStatus, SVNStatusType.STATUS_IGNORED)) { - boolean isIgnored = changeListManager.isIgnoredFile(addedFile); - if (!isIgnored) { - addedVFiles.add(addedFile); - copyFromMap.put(addedFile, addedFileInfo.myCopyFrom); - if (addedFileInfo.myRecursive) { - recursiveItems.add(addedFile); - } - } - } - } - } - } - - private void processDeletedFiles(Project project) { - final List deletedFiles = new ArrayList(); - final Collection filesToProcess = new ArrayList(); - fillDeletedFiles(project, deletedFiles, filesToProcess); - if (deletedFiles.isEmpty() && filesToProcess.isEmpty() || myUndoingMove) return; - SvnVcs vcs = SvnVcs.getInstance(project); - final VcsShowConfirmationOption.Value value = vcs.getDeleteConfirmation().getValue(); - if (value != VcsShowConfirmationOption.Value.DO_NOTHING_SILENTLY) { - final AbstractVcsHelper vcsHelper = AbstractVcsHelper.getInstance(project); - if (! deletedFiles.isEmpty()) { - final Collection confirmed = promptAboutDeletion(deletedFiles, vcs, value, vcsHelper); - if (confirmed != null) { - filesToProcess.addAll(confirmed); - } - } - if (filesToProcess != null && !filesToProcess.isEmpty()) { - List exceptions = new ArrayList(); - runInBackground(project, "Deleting files from Subversion", createDeleteRunnable(project, vcs, filesToProcess, exceptions)); - if (!exceptions.isEmpty()) { - vcsHelper.showErrors(exceptions, SvnBundle.message("delete.files.errors.title")); - } - } - for (FilePath file : deletedFiles) { - final FilePath parent = file.getParentPath(); - if (parent != null) { - myFilesToRefresh.add(parent.getVirtualFile()); - } - } - if (filesToProcess != null) { - deletedFiles.removeAll(filesToProcess); - } - for (FilePath file : deletedFiles) { - FileUtil.delete(file.getIOFile()); - } - } - } - - private Runnable createDeleteRunnable(final Project project, - final SvnVcs vcs, - final Collection filesToProcess, - final List exceptions) { - return new Runnable() { - public void run() { - final SVNWCClient wcClient = vcs.createWCClient(); - for(FilePath file: filesToProcess) { - VirtualFile vFile = file.getVirtualFile(); // for deleted directories - final File ioFile = new File(file.getPath()); - try { - new RepeatSvnActionThroughBusy() { - @Override - protected void executeImpl() throws SVNException { - wcClient.doDelete(ioFile, true, false); - } - }.execute(); - if (vFile != null && vFile.isValid() && vFile.isDirectory()) { - vFile.refresh(true, true); - VcsDirtyScopeManager.getInstance(project).dirDirtyRecursively(vFile); - } - else { - VcsDirtyScopeManager.getInstance(project).fileDirty(file); - } - } - catch (SVNException e) { - exceptions.add(new VcsException(e)); - } - } - } - }; - } - - private Collection promptAboutDeletion(List deletedFiles, - SvnVcs vcs, - VcsShowConfirmationOption.Value value, - AbstractVcsHelper vcsHelper) { - Collection filesToProcess; - if (value == VcsShowConfirmationOption.Value.DO_ACTION_SILENTLY) { - filesToProcess = new ArrayList(deletedFiles); - } - else { - - final String singleFilePrompt; - if (deletedFiles.size() == 1 && deletedFiles.get(0).isDirectory()) { - singleFilePrompt = SvnBundle.getString("confirmation.text.delete.dir"); - } - else { - singleFilePrompt = SvnBundle.getString("confirmation.text.delete.file"); - } - final Collection files = vcsHelper - .selectFilePathsToProcess(deletedFiles, SvnBundle.message("confirmation.title.delete.multiple.files"), null, - SvnBundle.message("confirmation.title.delete.file"), singleFilePrompt, vcs.getDeleteConfirmation()); - filesToProcess = files == null ? null : new ArrayList(files); - } - return filesToProcess; - } - - private void fillDeletedFiles(Project project, List deletedFiles, Collection deleteAnyway) { - final SvnVcs vcs = SvnVcs.getInstance(project); - final SVNStatusClient sc = vcs.createStatusClient(); - final Collection files = myDeletedFiles.remove(project); - for (final File file : files) { - boolean isAdded = false; - try { - final SVNStatus status = new RepeatSvnActionThroughBusy() { - @Override - protected void executeImpl() throws SVNException { - myT = sc.doStatus(file, false); - } - }.compute(); - isAdded = SVNStatusType.STATUS_ADDED.equals(status.getNodeStatus()); - } - catch (SVNException e) { - // - } - final FilePath filePath = VcsContextFactory.SERVICE.getInstance().createFilePathOn(file); - if (isAdded) { - deleteAnyway.add(filePath); - } else { - deletedFiles.add(filePath); - } - } - } - - private void processMovedFiles(final Project project) { - if (myMovedFiles.isEmpty()) return; - - final Runnable runnable = new Runnable() { - public void run() { - for (Iterator iterator = myMovedFiles.iterator(); iterator.hasNext();) { - MovedFileInfo movedFileInfo = iterator.next(); - if (movedFileInfo.myProject == project) { - doMove(SvnVcs.getInstance(project), movedFileInfo.mySrc, movedFileInfo.myDst); - iterator.remove(); - } - } - } - }; - runInBackground(project, "Moving files in Subversion", runnable); - } - - @Nullable - private static SvnVcs getVCS(VirtualFile file) { - Project[] projects = ProjectManager.getInstance().getOpenProjects(); - for (Project project : projects) { - AbstractVcs vcs = ProjectLevelVcsManager.getInstance(project).getVcsFor(file); - if (vcs instanceof SvnVcs) { - return (SvnVcs)vcs; - } - } - return null; - } - - - private static File getIOFile(VirtualFile vf) { - return new File(vf.getPath()).getAbsoluteFile(); - } - - @Nullable - private static SVNStatus getFileStatus(File file) { - final SVNClientManager clientManager = SVNClientManager.newInstance(); - try { - SVNStatusClient stClient = clientManager.getStatusClient(); - return getFileStatus(file, stClient); - } - finally { - clientManager.dispose(); - } - } - - @Nullable - private static SVNStatus getFileStatus(SvnVcs vcs, File file) { - SVNStatusClient stClient = vcs.createStatusClient(); - return getFileStatus(file, stClient); - } - - @Nullable - private static SVNStatus getFileStatus(final File file, final SVNStatusClient stClient) { - try { - return new RepeatSvnActionThroughBusy() { - @Override - protected void executeImpl() throws SVNException { - myT = stClient.doStatus(file, false); - } - }.compute(); - } - catch (SVNException e) { - return null; - } - } - - private static boolean isUndoOrRedo(@NotNull final Project project) { - final UndoManager undoManager = UndoManager.getInstance(project); - return undoManager.isUndoInProgress() || undoManager.isRedoInProgress(); - } - - private static boolean isUndo(SvnVcs vcs) { - if (vcs == null || vcs.getProject() == null) { - return false; - } - Project p = vcs.getProject(); - return UndoManager.getInstance(p).isUndoInProgress(); - } - - public void afterDone(final ThrowableConsumer invoker) { - } -} +/* + * Copyright 2000-2009 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.idea.svn; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandAdapter; +import com.intellij.openapi.command.CommandEvent; +import com.intellij.openapi.command.undo.UndoManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vcs.*; +import com.intellij.openapi.vcs.actions.VcsContextFactory; +import com.intellij.openapi.vcs.changes.ChangeListManager; +import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager; +import com.intellij.openapi.vfs.LocalFileOperationsHandler; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.newvfs.RefreshQueue; +import com.intellij.openapi.vfs.newvfs.RefreshSession; +import com.intellij.util.ThrowableConsumer; +import com.intellij.util.containers.MultiMap; +import com.intellij.vcsUtil.ActionWithTempFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.tmatesoft.svn.core.SVNErrorCode; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNNodeKind; +import org.tmatesoft.svn.core.internal.wc.SVNFileUtil; +import org.tmatesoft.svn.core.wc.*; + +import java.io.File; +import java.io.IOException; +import java.util.*; + +public class SvnFileSystemListener extends CommandAdapter implements LocalFileOperationsHandler { + private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.SvnFileSystemListener"); + private final LocalFileSystem myLfs; + + private static class AddedFileInfo { + private final VirtualFile myDir; + private final String myName; + @Nullable private final File myCopyFrom; + private final boolean myRecursive; + + public AddedFileInfo(final VirtualFile dir, final String name, @Nullable final File copyFrom, boolean recursive) { + myDir = dir; + myName = name; + myCopyFrom = copyFrom; + myRecursive = recursive; + } + } + + private static class MovedFileInfo { + private final Project myProject; + private final File mySrc; + private final File myDst; + + private MovedFileInfo(final Project project, final File src, final File dst) { + myProject = project; + mySrc = src; + myDst = dst; + } + } + + private final MultiMap myAddedFiles = new MultiMap(); + private final MultiMap myDeletedFiles = new MultiMap(); + private final List myMovedFiles = new ArrayList(); + private final Map> myMoveExceptions = new HashMap>(); + private final List myFilesToRefresh = new ArrayList(); + @Nullable private File myStorageForUndo; + private final List> myUndoStorageContents = new ArrayList>(); + private boolean myUndoingMove = false; + + public SvnFileSystemListener() { + myLfs = LocalFileSystem.getInstance(); + } + + private void addToMoveExceptions(final Project project, final SVNException e) { + List exceptionList = myMoveExceptions.get(project); + if (exceptionList == null) { + exceptionList = new ArrayList(); + myMoveExceptions.put(project, exceptionList); + } + VcsException vcsException; + if (SVNErrorCode.ENTRY_EXISTS.equals(e.getErrorMessage().getErrorCode())) { + vcsException = new VcsException(Arrays.asList("Target of move operation is already under version control.", + "Subversion move had not been performed. ", e.getMessage())); + } else { + vcsException = new VcsException(e); + } + exceptionList.add(vcsException); + } + + @Nullable + public File copy(final VirtualFile file, final VirtualFile toDir, final String copyName) throws IOException { + SvnVcs vcs = getVCS(toDir); + if (vcs == null) { + vcs = getVCS(file); + } + if (vcs == null) { + return null; + } + + File srcFile = new File(file.getPath()); + File destFile = new File(new File(toDir.getPath()), copyName); + final boolean dstDirUnderControl = SvnUtil.isSvnVersioned(vcs.getProject(), destFile.getParentFile()); + if (! dstDirUnderControl && !isPendingAdd(vcs.getProject(), toDir)) { + return null; + } + + if (! SvnUtil.isSvnVersioned(vcs.getProject(), srcFile.getParentFile())) { + myAddedFiles.putValue(vcs.getProject(), new AddedFileInfo(toDir, copyName, null, false)); + return null; + } + + final SVNStatus fileStatus = getFileStatus(vcs, srcFile); + if (fileStatus != null && SvnVcs.svnStatusIs(fileStatus, SVNStatusType.STATUS_ADDED)) { + myAddedFiles.putValue(vcs.getProject(), new AddedFileInfo(toDir, copyName, null, false)); + return null; + } + + if (sameRoot(vcs, file.getParent(), toDir)) { + myAddedFiles.putValue(vcs.getProject(), new AddedFileInfo(toDir, copyName, srcFile, false)); + return null; + } + + myAddedFiles.putValue(vcs.getProject(), new AddedFileInfo(toDir, copyName, null, false)); + return null; + } + + private boolean sameRoot(final SvnVcs vcs, final VirtualFile srcDir, final VirtualFile dstDir) { + final UUIDHelper helper = new UUIDHelper(vcs); + final String srcUUID = helper.getRepositoryUUID(vcs.getProject(), srcDir); + final String dstUUID = helper.getRepositoryUUID(vcs.getProject(), dstDir); + + return srcUUID != null && dstUUID != null && srcUUID.equals(dstUUID); + } + + private class UUIDHelper { + private final SVNWCClient myWcClient; + + private UUIDHelper(final SvnVcs vcs) { + myWcClient = vcs.createWCClient(); + } + + /** + * passed dir must be under VC control (it is assumed) + */ + @Nullable + public String getRepositoryUUID(final Project project, final VirtualFile dir) { + try { + final SVNInfo info1 = new RepeatSvnActionThroughBusy() { + @Override + protected void executeImpl() throws SVNException { + myT = myWcClient.doInfo(new File(dir.getPath()), SVNRevision.UNDEFINED); + } + }.compute(); + if (info1 == null || info1.getRepositoryUUID() == null) { + // go deeper if current parent was added (if parent was added, it theoretically could NOT know its repo UUID) + final VirtualFile parent = dir.getParent(); + if (parent == null) { + return null; + } + if (isPendingAdd(project, parent)) { + return getRepositoryUUID(project, parent); + } + } else { + return info1.getRepositoryUUID(); + } + } catch (SVNException e) { + // go to return default + } + return null; + } + } + + public boolean move(VirtualFile file, VirtualFile toDir) throws IOException { + File srcFile = getIOFile(file); + File dstFile = new File(getIOFile(toDir), file.getName()); + + final SvnVcs vcs = getVCS(toDir); + final SvnVcs sourceVcs = getVCS(file); + if (vcs == null && sourceVcs == null) return false; + + if (vcs == null) { + return false; + } + if (sourceVcs == null) { + return createItem(toDir, file.getName(), file.isDirectory(), true); + } + + if (isPendingAdd(vcs.getProject(), toDir)) { + + myMovedFiles.add(new MovedFileInfo(sourceVcs.getProject(), srcFile, dstFile)); + return true; + } + else { + final VirtualFile oldParent = file.getParent(); + myFilesToRefresh.add(oldParent); + myFilesToRefresh.add(toDir); + return doMove(sourceVcs, srcFile, dstFile); + } + } + + public boolean rename(VirtualFile file, String newName) throws IOException { + File srcFile = getIOFile(file); + File dstFile = new File(srcFile.getParentFile(), newName); + SvnVcs vcs = getVCS(file); + if (vcs != null) { + myFilesToRefresh.add(file.getParent()); + return doMove(vcs, srcFile, dstFile); + } + return false; + } + + private boolean doMove(@NotNull SvnVcs vcs, final File src, final File dst) { + long srcTime = src.lastModified(); + try { + final boolean isUndo = isUndo(vcs); + final String list = isUndo ? null : SvnChangelistListener.getCurrentMapping(vcs.getProject(), src); + + final boolean is17 = SvnUtil.is17CopyPart(src); + if (is17) { + if (for17move(vcs, src, dst, isUndo)) return false; + } else { + if (for16move(vcs, src, dst, isUndo)) return false; + } + + if (! isUndo && list != null) { + SvnChangelistListener.putUnderList(vcs.getProject(), list, dst); + } + dst.setLastModified(srcTime); + } + catch (SVNException e) { + addToMoveExceptions(vcs.getProject(), e); + return false; + } + return true; + } + + private boolean for17move(SvnVcs vcs, final File src, final File dst, boolean undo) throws SVNException { + if (undo) { + final SVNWCClient wcClient = vcs.createWCClient(); + myUndoingMove = true; + new RepeatSvnActionThroughBusy() { + @Override + protected void executeImpl() throws SVNException { + wcClient.doRevert(dst, true); + } + }.execute(); + new RepeatSvnActionThroughBusy() { + @Override + protected void executeImpl() throws SVNException { + wcClient.doRevert(src, true); + } + }.execute(); + restoreFromUndoStorage(dst); + } else { + if (doUsualMove(vcs, src)) return true; + final SVNCopyClient copyClient = vcs.createCopyClient(); + final SVNCopySource svnCopySource = new SVNCopySource(SVNRevision.UNDEFINED, SVNRevision.WORKING, src); + new RepeatSvnActionThroughBusy() { + @Override + protected void executeImpl() throws SVNException { + copyClient.doCopy(new SVNCopySource[]{svnCopySource}, dst, true, false, true); + } + }.execute(); + } + return false; + } + + private boolean doUsualMove(SvnVcs vcs, File src) { + // if src is not under version control, do usual move. + SVNStatus srcStatus = getFileStatus(vcs, src); + if (srcStatus == null || SvnVcs.svnStatusIsUnversioned(srcStatus) || + SvnVcs.svnStatusIs(srcStatus, SVNStatusType.STATUS_OBSTRUCTED) || + SvnVcs.svnStatusIs(srcStatus, SVNStatusType.STATUS_MISSING) || + SvnVcs.svnStatusIs(srcStatus, SVNStatusType.STATUS_EXTERNAL)) { + return true; + } + return false; + } + + private boolean for16move(SvnVcs vcs, final File src, final File dst, boolean undo) throws SVNException { + final SVNMoveClient mover = vcs.createMoveClient(); + if (undo) { + myUndoingMove = true; + restoreFromUndoStorage(dst); + new RepeatSvnActionThroughBusy() { + @Override + protected void executeImpl() throws SVNException { + mover.undoMove(src, dst); + } + }.execute(); + } + else { + // if src is not under version control, do usual move. + if (doUsualMove(vcs, src)) return true; + new RepeatSvnActionThroughBusy() { + @Override + protected void executeImpl() throws SVNException { + mover.doMove(src, dst); + } + }.execute(); + } + return false; + } + + private void restoreFromUndoStorage(final File dst) { + String normPath = FileUtil.toSystemIndependentName(dst.getPath()); + for (Iterator> it = myUndoStorageContents.iterator(); it.hasNext();) { + Pair e = it.next(); + final String p = FileUtil.toSystemIndependentName(e.first.getPath()); + if (p.startsWith(normPath)) { + try { + FileUtil.rename(e.second, e.first); + } + catch (IOException ex) { + LOG.error(ex); + FileUtil.asyncDelete(e.second); + } + it.remove(); + } + } + if (myStorageForUndo != null) { + final File[] files = myStorageForUndo.listFiles(); + if (files == null || files.length == 0) { + FileUtil.asyncDelete(myStorageForUndo); + myStorageForUndo = null; + } + } + } + + + public boolean createFile(VirtualFile dir, String name) throws IOException { + return createItem(dir, name, false, false); + } + + public boolean createDirectory(VirtualFile dir, String name) throws IOException { + return createItem(dir, name, true, false); + } + + /** + * delete file or directory (both 'undo' and 'do' modes) + * unversioned: do nothing, return false + * obstructed: do nothing, return false + * external or wc root: do nothing, return false + * missing: do nothing, return false + *

    + * versioned: schedule for deletion, return true + * added: schedule for deletion (make unversioned), return true + * copied, but not scheduled: schedule for deletion, return true + * replaced: schedule for deletion, return true + *

    + * deleted: do nothing, return true (strange) + */ + public boolean delete(VirtualFile file) throws IOException { + SvnVcs vcs = getVCS(file); + if (vcs != null && SvnUtil.isAdminDirectory(file)) { + return true; + } + if (vcs == null) return false; + final File ioFile = getIOFile(file); + if (! SvnUtil.isSvnVersioned(vcs.getProject(), ioFile.getParentFile())) { + return false; + } + try { + if (SVNWCUtil.isWorkingCopyRoot(ioFile)) { + return false; + } + } catch (SVNException e) { + // + } + + SVNStatus status = getFileStatus(ioFile); + + if (status == null || + SvnVcs.svnStatusIsUnversioned(status) || + SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_OBSTRUCTED) || + SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_MISSING) || + SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_EXTERNAL) || + SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_IGNORED)) { + return false; + } else if (SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_DELETED)) { + if (isUndo(vcs)) { + moveToUndoStorage(file); + } + return true; + } + else { + if (vcs != null) { + if (isAboveSourceOfCopyOrMove(vcs.getProject(), ioFile)) { + myDeletedFiles.putValue(vcs.getProject(), ioFile); + return true; + } + if (SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_ADDED)) { + try { + final SVNWCClient wcClient = vcs.createWCClient(); + new RepeatSvnActionThroughBusy() { + @Override + protected void executeImpl() throws SVNException { + wcClient.doRevert(ioFile, false); + } + }.execute(); + } + catch (SVNException e) { + // ignore + } + } + else { + myDeletedFiles.putValue(vcs.getProject(), ioFile); + // packages deleted from disk should not be deleted from svn (IDEADEV-16066) + if (file.isDirectory() || isUndo(vcs)) return true; + } + } + return false; + } + } + + private boolean isAboveSourceOfCopyOrMove(final Project p, File ioFile) { + for (MovedFileInfo file : myMovedFiles) { + if (FileUtil.isAncestor(ioFile, file.mySrc, false)) return true; + } + for (AddedFileInfo info : myAddedFiles.get(p)) { + if (info.myCopyFrom != null && FileUtil.isAncestor(ioFile, info.myCopyFrom, false)) return true; + } + return false; + } + + private void moveToUndoStorage(final VirtualFile file) { + if (myStorageForUndo == null) { + try { + myStorageForUndo = FileUtil.createTempDirectory("svnUndoStorage", ""); + } + catch (IOException e) { + LOG.error(e); + return; + } + } + final File tmpFile = FileUtil.findSequentNonexistentFile(myStorageForUndo, "tmp", ""); + myUndoStorageContents.add(0, new Pair(new File(file.getPath()), tmpFile)); + new File(file.getPath()).renameTo(tmpFile); + } + + /** + * add file or directory: + *

    + * parent directory is: + * unversioned: do nothing, return false + * versioned: + * entry is: + * null: create entry, schedule for addition + * missing: do nothing, return false + * deleted, 'do' mode: try to create entry and it schedule for addition if kind is the same, otherwise do nothing, return false. + * deleted: 'undo' mode: try to revert non-recursively, if kind is the same, otherwise do nothing, return false. + * anything else: return false. + */ + private boolean createItem(VirtualFile dir, String name, boolean directory, final boolean recursive) { + SvnVcs vcs = getVCS(dir); + if (vcs == null) { + return false; + } + if (isUndo(vcs) && SvnUtil.isAdminDirectory(dir, name)) { + return false; + } + File ioDir = getIOFile(dir); + boolean pendingAdd = isPendingAdd(vcs.getProject(), dir); + if (! SvnUtil.isSvnVersioned(vcs.getProject(), ioDir) && ! pendingAdd) { + return false; + } + final SVNWCClient wcClient = vcs.createWCClient(); + final File targetFile = new File(ioDir, name); + SVNStatus status = getFileStatus(vcs, targetFile); + + if (status == null || status.getContentsStatus() == SVNStatusType.STATUS_NONE || + status.getContentsStatus() == SVNStatusType.STATUS_UNVERSIONED) { + myAddedFiles.putValue(vcs.getProject(), new AddedFileInfo(dir, name, null, recursive)); + return false; + } + else if (SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_MISSING)) { + return false; + } + else if (SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_DELETED)) { + SVNNodeKind kind = status.getKind(); + // kind differs. + if (directory && kind != SVNNodeKind.DIR || !directory && kind != SVNNodeKind.FILE) { + return false; + } + try { + if (isUndo(vcs)) { + new RepeatSvnActionThroughBusy() { + @Override + protected void executeImpl() throws SVNException { + wcClient.doRevert(targetFile, false); + } + }.execute(); + return true; + } + myAddedFiles.putValue(vcs.getProject(), new AddedFileInfo(dir, name, null, recursive)); + return false; + } + catch (SVNException e) { + SVNFileUtil.deleteAll(targetFile, true); + return false; + } + } + return false; + } + + private boolean isPendingAdd(final Project project, final VirtualFile dir) { + final Collection addedFileInfos = myAddedFiles.get(project); + for(AddedFileInfo i: addedFileInfos) { + if (Comparing.equal(i.myDir, dir.getParent()) && i.myName.equals(dir.getName())) { + return true; + } + } + return false; + } + + public void commandStarted(CommandEvent event) { + myUndoingMove = false; + final Project project = event.getProject(); + if (project == null) return; + commandStarted(project); + } + + void commandStarted(final Project project) { + myUndoingMove = false; + myMoveExceptions.remove(project); + } + + public void commandFinished(CommandEvent event) { + final Project project = event.getProject(); + if (project == null) return; + commandFinished(project); + } + + void commandFinished(final Project project) { + checkOverwrites(project); + if (myAddedFiles.containsKey(project)) { + processAddedFiles(project); + } + processMovedFiles(project); + if (myDeletedFiles.containsKey(project)) { + processDeletedFiles(project); + } + + final List exceptionList = myMoveExceptions.get(project); + if (exceptionList != null && ! exceptionList.isEmpty()) { + AbstractVcsHelper.getInstance(project).showErrors(exceptionList, SvnBundle.message("move.files.errors.title")); + } + + if (!myFilesToRefresh.isEmpty()) { + refreshFiles(project); + } + } + + private void checkOverwrites(final Project project) { + final Collection addedFileInfos = myAddedFiles.get(project); + final Collection deletedFiles = myDeletedFiles.get(project); + if (addedFileInfos.isEmpty() || deletedFiles.isEmpty()) return; + final Iterator iterator = addedFileInfos.iterator(); + while (iterator.hasNext()) { + AddedFileInfo addedFileInfo = iterator.next(); + final File ioFile = new File(addedFileInfo.myDir.getPath(), addedFileInfo.myName); + if (deletedFiles.remove(ioFile)) { + iterator.remove(); + } + } + } + + private void refreshFiles(final Project project) { + final List toRefreshFiles = new ArrayList(); + final List toRefreshDirs = new ArrayList(); + for (VirtualFile file : myFilesToRefresh) { + if (file == null) continue; + if (file.isDirectory()) { + toRefreshDirs.add(file); + } else { + toRefreshFiles.add(file); + } + } + // if refresh asynchronously, local changes would also be notified that they are dirty asynchronously, + // and commit could be executed while not all changes are visible + final RefreshSession session = RefreshQueue.getInstance().createSession(true, true, new Runnable() { + public void run() { + if (project.isDisposed()) return; + filterOutInvalid(toRefreshFiles); + filterOutInvalid(toRefreshDirs); + + final VcsDirtyScopeManager vcsDirtyScopeManager = VcsDirtyScopeManager.getInstance(project); + vcsDirtyScopeManager.filesDirty(toRefreshFiles, toRefreshDirs); + } + }); + filterOutInvalid(myFilesToRefresh); + session.addAllFiles(myFilesToRefresh); + session.launch(); + myFilesToRefresh.clear(); + } + + private static void filterOutInvalid(final Collection files) { + for (Iterator iterator = files.iterator(); iterator.hasNext();) { + final VirtualFile file = iterator.next(); + if (! file.isValid() || ! file.exists()) { + LOG.info("Refresh root is not valid: " + file.getPath()); + iterator.remove(); + } + } + } + + private void processAddedFiles(Project project) { + SvnVcs vcs = SvnVcs.getInstance(project); + List addedVFiles = new ArrayList(); + Map copyFromMap = new HashMap(); + final Set recursiveItems = new HashSet(); + fillAddedFiles(project, vcs, addedVFiles, copyFromMap, recursiveItems); + if (addedVFiles.isEmpty()) return; + final VcsShowConfirmationOption.Value value = vcs.getAddConfirmation().getValue(); + if (value != VcsShowConfirmationOption.Value.DO_NOTHING_SILENTLY) { + final AbstractVcsHelper vcsHelper = AbstractVcsHelper.getInstance(project); + final Collection filesToProcess = promptAboutAddition(vcs, addedVFiles, value, vcsHelper); + if (filesToProcess != null && !filesToProcess.isEmpty()) { + final List exceptions = new ArrayList(); + runInBackground(project, "Adding files to Subversion", + createAdditionRunnable(project, vcs, copyFromMap, filesToProcess, exceptions)); + if (!exceptions.isEmpty()) { + vcsHelper.showErrors(exceptions, SvnBundle.message("add.files.errors.title")); + } + } + } + } + + private void runInBackground(final Project project, final String name, final Runnable runnable) { + if (ApplicationManager.getApplication().isDispatchThread()) { + ProgressManager.getInstance().runProcessWithProgressSynchronously(runnable, name, false, project); + } else { + runnable.run(); + } + } + + private Runnable createAdditionRunnable(final Project project, + final SvnVcs vcs, + final Map copyFromMap, + final Collection filesToProcess, + final List exceptions) { + return new Runnable() { + @Override + public void run() { + final SVNWCClient wcClient = vcs.createWCClient(); + final SVNCopyClient copyClient = vcs.createCopyClient(); + for(VirtualFile file: filesToProcess) { + final File ioFile = new File(file.getPath()); + try { + final File copyFrom = copyFromMap.get(file); + if (copyFrom != null) { + try { + new ActionWithTempFile(ioFile) { + protected void executeInternal() throws VcsException { + try { + // not recursive + final SVNCopySource[] copySource = {new SVNCopySource(SVNRevision.WORKING, SVNRevision.WORKING, copyFrom)}; + new RepeatSvnActionThroughBusy() { + @Override + protected void executeImpl() throws SVNException { + copyClient.doCopy(copySource, ioFile, false, true, true); + } + }.execute(); + } + catch (SVNException e) { + throw new VcsException(e); + } + } + }.execute(); + } + catch (VcsException e) { + exceptions.add(e); + } + } + else { + new RepeatSvnActionThroughBusy() { + @Override + protected void executeImpl() throws SVNException { + wcClient.doAdd(ioFile, true, false, false, true); + } + }.execute(); + } + VcsDirtyScopeManager.getInstance(project).fileDirty(file); + } + catch (SVNException e) { + exceptions.add(new VcsException(e)); + } + } + } + }; + } + + private Collection promptAboutAddition(SvnVcs vcs, + List addedVFiles, + VcsShowConfirmationOption.Value value, + AbstractVcsHelper vcsHelper) { + Collection filesToProcess; + if (value == VcsShowConfirmationOption.Value.DO_ACTION_SILENTLY) { + filesToProcess = addedVFiles; + } + else { + final String singleFilePrompt; + if (addedVFiles.size() == 1 && addedVFiles.get(0).isDirectory()) { + singleFilePrompt = SvnBundle.getString("confirmation.text.add.dir"); + } + else { + singleFilePrompt = SvnBundle.getString("confirmation.text.add.file"); + } + filesToProcess = vcsHelper.selectFilesToProcess(addedVFiles, SvnBundle.message("confirmation.title.add.multiple.files"), + null, + SvnBundle.message("confirmation.title.add.file"), singleFilePrompt, + vcs.getAddConfirmation()); + } + return filesToProcess; + } + + private void fillAddedFiles(Project project, + SvnVcs vcs, + List addedVFiles, + Map copyFromMap, + Set recursiveItems) { + final Collection addedFileInfos = myAddedFiles.remove(project); + final ChangeListManager changeListManager = ChangeListManager.getInstance(project); + + for (AddedFileInfo addedFileInfo : addedFileInfos) { + final File ioFile = new File(getIOFile(addedFileInfo.myDir), addedFileInfo.myName); + VirtualFile addedFile = addedFileInfo.myDir.findChild(addedFileInfo.myName); + if (addedFile == null) { + addedFile = myLfs.refreshAndFindFileByIoFile(ioFile); + } + if (addedFile != null) { + final SVNStatus fileStatus = getFileStatus(vcs, ioFile); + if (fileStatus == null || ! SvnVcs.svnStatusIs(fileStatus, SVNStatusType.STATUS_IGNORED)) { + boolean isIgnored = changeListManager.isIgnoredFile(addedFile); + if (!isIgnored) { + addedVFiles.add(addedFile); + copyFromMap.put(addedFile, addedFileInfo.myCopyFrom); + if (addedFileInfo.myRecursive) { + recursiveItems.add(addedFile); + } + } + } + } + } + } + + private void processDeletedFiles(Project project) { + final List deletedFiles = new ArrayList(); + final Collection filesToProcess = new ArrayList(); + fillDeletedFiles(project, deletedFiles, filesToProcess); + if (deletedFiles.isEmpty() && filesToProcess.isEmpty() || myUndoingMove) return; + SvnVcs vcs = SvnVcs.getInstance(project); + final VcsShowConfirmationOption.Value value = vcs.getDeleteConfirmation().getValue(); + if (value != VcsShowConfirmationOption.Value.DO_NOTHING_SILENTLY) { + final AbstractVcsHelper vcsHelper = AbstractVcsHelper.getInstance(project); + if (! deletedFiles.isEmpty()) { + final Collection confirmed = promptAboutDeletion(deletedFiles, vcs, value, vcsHelper); + if (confirmed != null) { + filesToProcess.addAll(confirmed); + } + } + if (filesToProcess != null && !filesToProcess.isEmpty()) { + List exceptions = new ArrayList(); + runInBackground(project, "Deleting files from Subversion", createDeleteRunnable(project, vcs, filesToProcess, exceptions)); + if (!exceptions.isEmpty()) { + vcsHelper.showErrors(exceptions, SvnBundle.message("delete.files.errors.title")); + } + } + for (FilePath file : deletedFiles) { + final FilePath parent = file.getParentPath(); + if (parent != null) { + myFilesToRefresh.add(parent.getVirtualFile()); + } + } + if (filesToProcess != null) { + deletedFiles.removeAll(filesToProcess); + } + for (FilePath file : deletedFiles) { + FileUtil.delete(file.getIOFile()); + } + } + } + + private Runnable createDeleteRunnable(final Project project, + final SvnVcs vcs, + final Collection filesToProcess, + final List exceptions) { + return new Runnable() { + public void run() { + final SVNWCClient wcClient = vcs.createWCClient(); + for(FilePath file: filesToProcess) { + VirtualFile vFile = file.getVirtualFile(); // for deleted directories + final File ioFile = new File(file.getPath()); + try { + new RepeatSvnActionThroughBusy() { + @Override + protected void executeImpl() throws SVNException { + wcClient.doDelete(ioFile, true, false); + } + }.execute(); + if (vFile != null && vFile.isValid() && vFile.isDirectory()) { + vFile.refresh(true, true); + VcsDirtyScopeManager.getInstance(project).dirDirtyRecursively(vFile); + } + else { + VcsDirtyScopeManager.getInstance(project).fileDirty(file); + } + } + catch (SVNException e) { + exceptions.add(new VcsException(e)); + } + } + } + }; + } + + private Collection promptAboutDeletion(List deletedFiles, + SvnVcs vcs, + VcsShowConfirmationOption.Value value, + AbstractVcsHelper vcsHelper) { + Collection filesToProcess; + if (value == VcsShowConfirmationOption.Value.DO_ACTION_SILENTLY) { + filesToProcess = new ArrayList(deletedFiles); + } + else { + + final String singleFilePrompt; + if (deletedFiles.size() == 1 && deletedFiles.get(0).isDirectory()) { + singleFilePrompt = SvnBundle.getString("confirmation.text.delete.dir"); + } + else { + singleFilePrompt = SvnBundle.getString("confirmation.text.delete.file"); + } + final Collection files = vcsHelper + .selectFilePathsToProcess(deletedFiles, SvnBundle.message("confirmation.title.delete.multiple.files"), null, + SvnBundle.message("confirmation.title.delete.file"), singleFilePrompt, vcs.getDeleteConfirmation()); + filesToProcess = files == null ? null : new ArrayList(files); + } + return filesToProcess; + } + + private void fillDeletedFiles(Project project, List deletedFiles, Collection deleteAnyway) { + final SvnVcs vcs = SvnVcs.getInstance(project); + final SVNStatusClient sc = vcs.createStatusClient(); + final Collection files = myDeletedFiles.remove(project); + for (final File file : files) { + boolean isAdded = false; + try { + final SVNStatus status = new RepeatSvnActionThroughBusy() { + @Override + protected void executeImpl() throws SVNException { + myT = sc.doStatus(file, false); + } + }.compute(); + isAdded = SVNStatusType.STATUS_ADDED.equals(status.getNodeStatus()); + } + catch (SVNException e) { + // + } + final FilePath filePath = VcsContextFactory.SERVICE.getInstance().createFilePathOn(file); + if (isAdded) { + deleteAnyway.add(filePath); + } else { + deletedFiles.add(filePath); + } + } + } + + private void processMovedFiles(final Project project) { + if (myMovedFiles.isEmpty()) return; + + final Runnable runnable = new Runnable() { + public void run() { + for (Iterator iterator = myMovedFiles.iterator(); iterator.hasNext();) { + MovedFileInfo movedFileInfo = iterator.next(); + if (movedFileInfo.myProject == project) { + doMove(SvnVcs.getInstance(project), movedFileInfo.mySrc, movedFileInfo.myDst); + iterator.remove(); + } + } + } + }; + runInBackground(project, "Moving files in Subversion", runnable); + } + + @Nullable + private static SvnVcs getVCS(VirtualFile file) { + Project[] projects = ProjectManager.getInstance().getOpenProjects(); + for (Project project : projects) { + AbstractVcs vcs = ProjectLevelVcsManager.getInstance(project).getVcsFor(file); + if (vcs instanceof SvnVcs) { + return (SvnVcs)vcs; + } + } + return null; + } + + + private static File getIOFile(VirtualFile vf) { + return new File(vf.getPath()).getAbsoluteFile(); + } + + @Nullable + private static SVNStatus getFileStatus(File file) { + final SVNClientManager clientManager = SVNClientManager.newInstance(); + try { + SVNStatusClient stClient = clientManager.getStatusClient(); + return getFileStatus(file, stClient); + } + finally { + clientManager.dispose(); + } + } + + @Nullable + private static SVNStatus getFileStatus(SvnVcs vcs, File file) { + SVNStatusClient stClient = vcs.createStatusClient(); + return getFileStatus(file, stClient); + } + + @Nullable + private static SVNStatus getFileStatus(final File file, final SVNStatusClient stClient) { + try { + return new RepeatSvnActionThroughBusy() { + @Override + protected void executeImpl() throws SVNException { + myT = stClient.doStatus(file, false); + } + }.compute(); + } + catch (SVNException e) { + return null; + } + } + + private static boolean isUndoOrRedo(@NotNull final Project project) { + final UndoManager undoManager = UndoManager.getInstance(project); + return undoManager.isUndoInProgress() || undoManager.isRedoInProgress(); + } + + private static boolean isUndo(SvnVcs vcs) { + if (vcs == null || vcs.getProject() == null) { + return false; + } + Project p = vcs.getProject(); + return UndoManager.getInstance(p).isUndoInProgress(); + } + + public void afterDone(final ThrowableConsumer invoker) { + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnFileAnnotation.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnFileAnnotation.java index fcff85f5a40a..65571b3ecb0d 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnFileAnnotation.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnFileAnnotation.java @@ -15,6 +15,7 @@ */ package org.jetbrains.idea.svn.annotate; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vcs.annotate.AnnotationListener; import com.intellij.openapi.vcs.annotate.ShowAllAffectedGenericAction; import com.intellij.openapi.vcs.history.VcsRevisionNumber; @@ -27,7 +28,7 @@ public class SvnFileAnnotation extends BaseSvnFileAnnotation { private final VirtualFile myFile; private final SvnEntriesListener myListener = new SvnEntriesListener() { public void onEntriesChanged(VirtualFile directory) { - if (directory != myFile.getParent()) return; + if (!Comparing.equal(directory, myFile.getParent())) return; final VcsRevisionNumber currentRevision = myVcs.getDiffProvider().getCurrentRevision(myFile); if (currentRevision != null && currentRevision.equals(myBaseRevision)) return; diff --git a/plugins/svn4ideaOld/src/org/jetbrains/idea/svn/SvnFileSystemListener.java b/plugins/svn4ideaOld/src/org/jetbrains/idea/svn/SvnFileSystemListener.java index e2f7fb97f110..5732651ab052 100644 --- a/plugins/svn4ideaOld/src/org/jetbrains/idea/svn/SvnFileSystemListener.java +++ b/plugins/svn4ideaOld/src/org/jetbrains/idea/svn/SvnFileSystemListener.java @@ -25,6 +25,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vcs.*; @@ -439,7 +440,7 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp private boolean isPendingAdd(final Project project, final VirtualFile dir) { final Collection addedFileInfos = myAddedFiles.get(project); for(AddedFileInfo i: addedFileInfos) { - if (i.myDir == dir.getParent() && i.myName.equals(dir.getName())) { + if (Comparing.equal(i.myDir, dir.getParent()) && i.myName.equals(dir.getName())) { return true; } } diff --git a/plugins/svn4ideaOld/src/org/jetbrains/idea/svn/annotate/SvnFileAnnotation.java b/plugins/svn4ideaOld/src/org/jetbrains/idea/svn/annotate/SvnFileAnnotation.java index e4329a259887..a94fb2b1db22 100644 --- a/plugins/svn4ideaOld/src/org/jetbrains/idea/svn/annotate/SvnFileAnnotation.java +++ b/plugins/svn4ideaOld/src/org/jetbrains/idea/svn/annotate/SvnFileAnnotation.java @@ -15,6 +15,7 @@ */ package org.jetbrains.idea.svn.annotate; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vcs.annotate.*; import com.intellij.openapi.vcs.history.VcsFileRevision; import com.intellij.openapi.vcs.history.VcsRevisionNumber; @@ -104,7 +105,7 @@ public class SvnFileAnnotation implements FileAnnotation { }; private final SvnEntriesListener myListener = new SvnEntriesListener() { public void onEntriesChanged(VirtualFile directory) { - if (directory != myFile.getParent()) return; + if (!Comparing.equal(directory, myFile.getParent())) return; final VcsRevisionNumber currentRevision = myVcs.getDiffProvider().getCurrentRevision(myFile); if (currentRevision != null && currentRevision.equals(myBaseRevision)) return; diff --git a/plugins/ui-designer/testSrc/com/intellij/uiDesigner/core/AsmCodeGeneratorTest.java b/plugins/ui-designer/testSrc/com/intellij/uiDesigner/core/AsmCodeGeneratorTest.java index a5630623c131..c41db743dab4 100644 --- a/plugins/ui-designer/testSrc/com/intellij/uiDesigner/core/AsmCodeGeneratorTest.java +++ b/plugins/ui-designer/testSrc/com/intellij/uiDesigner/core/AsmCodeGeneratorTest.java @@ -30,6 +30,7 @@ import com.intellij.uiDesigner.lw.CompiledClassPropertiesProvider; import com.intellij.uiDesigner.lw.LwRootContainer; import com.intellij.util.PathUtil; import com.intellij.util.ui.UIUtil; +import gnu.trove.TIntObjectHashMap; import junit.framework.TestCase; import org.jetbrains.asm4.ClassWriter; @@ -65,6 +66,7 @@ public class AsmCodeGeneratorTest extends TestCase { java.util.List cp = new ArrayList(); appendPath(cp, JBTabbedPane.class); + appendPath(cp, TIntObjectHashMap.class); appendPath(cp, UIUtil.class); appendPath(cp, SystemInfoRt.class); appendPath(cp, ApplicationManager.class); @@ -319,7 +321,7 @@ public class AsmCodeGeneratorTest extends TestCase { assertTrue(panel.getBorder() instanceof TitledBorder); TitledBorder border = (TitledBorder) panel.getBorder(); assertEquals("BorderTitle", border.getTitle()); - assertTrue(border.getBorder() instanceof EtchedBorder); + assertTrue(border.getBorder().toString(), border.getBorder() instanceof EtchedBorder); } public void testMnemonic() throws Exception { diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltIncludeIndex.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltIncludeIndex.java index b15d485771ea..1c3866c13162 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltIncludeIndex.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltIncludeIndex.java @@ -17,6 +17,7 @@ package org.intellij.lang.xpath.xslt.impl; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; @@ -46,7 +47,7 @@ public class XsltIncludeIndex { //noinspection ForLoopReplaceableByForEach for (int i = 0; i < which.length; i++) { final VirtualFile file = which[i]; - if (file == from) { + if (Comparing.equal(file, from)) { return true; } } diff --git a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/CreateNSDeclarationIntentionFix.java b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/CreateNSDeclarationIntentionFix.java index 8d98f7fe61f9..21c8b0dbb5f6 100644 --- a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/CreateNSDeclarationIntentionFix.java +++ b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/CreateNSDeclarationIntentionFix.java @@ -37,6 +37,7 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.PopupChooserBuilder; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiAnchor; import com.intellij.psi.PsiDocumentManager; @@ -129,7 +130,7 @@ public class CreateNSDeclarationIntentionFix implements HintAction, LocalQuickFi final PsiFile containingFile = descriptor.getPsiElement().getContainingFile(); Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); final PsiFile file = editor != null ? PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()):null; - if (file == null || file.getVirtualFile() != containingFile.getVirtualFile()) return; + if (file == null || !Comparing.equal(file.getVirtualFile(), containingFile.getVirtualFile())) return; try { invoke(project, editor, containingFile); } catch (IncorrectOperationException ex) { LOG.error(ex); diff --git a/xml/impl/src/com/intellij/xml/breadcrumbs/BreadcrumbsXmlWrapper.java b/xml/impl/src/com/intellij/xml/breadcrumbs/BreadcrumbsXmlWrapper.java index d1b16c25325c..56b9b063d118 100644 --- a/xml/impl/src/com/intellij/xml/breadcrumbs/BreadcrumbsXmlWrapper.java +++ b/xml/impl/src/com/intellij/xml/breadcrumbs/BreadcrumbsXmlWrapper.java @@ -29,6 +29,7 @@ import com.intellij.openapi.editor.event.CaretListener; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.TextRange; @@ -119,7 +120,7 @@ public class BreadcrumbsXmlWrapper implements BreadcrumbsItemListener