diff --git a/RegExpSupport/src/org/intellij/lang/regexp/intention/CheckRegExpForm.java b/RegExpSupport/src/org/intellij/lang/regexp/intention/CheckRegExpForm.java index 51fc45789200..242dae54255b 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/intention/CheckRegExpForm.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/intention/CheckRegExpForm.java @@ -157,7 +157,7 @@ public class CheckRegExpForm { myRootPanel.revalidate(); Balloon balloon = JBPopupFactory.getInstance().getParentBalloonFor(myRootPanel); if (balloon != null) balloon.revalidate(); - }, ModalityState.current()); + }); } @TestOnly diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index 1a648d2a1aed..d9d81f92a0c5 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -732,7 +732,18 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh } } if (!myHolder.hasErrorResults()) { - final PsiElement resolved = results.length == 1 ? results[0].getElement() : null; + PsiElement resolved = results.length >= 1 ? results[0].getElement() : null; + if (results.length > 1) { + for (int i = 1; i < results.length; i++) { + final PsiElement element = results[i].getElement(); + if (resolved instanceof PsiMethod && !(element instanceof PsiMethod) || + resolved instanceof PsiVariable && !(element instanceof PsiVariable) || + resolved instanceof PsiClass && !(element instanceof PsiClass)) { + resolved = null; + break; + } + } + } final TextAttributesScheme colorsScheme = myHolder.getColorsScheme(); if (resolved instanceof PsiClass) { myHolder.add(HighlightNamesUtil.highlightClassName((PsiClass)resolved, ref, colorsScheme)); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMemberFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMemberFix.java index 48d9d24ad0e5..0134261cbf03 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMemberFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMemberFix.java @@ -24,17 +24,13 @@ import com.intellij.codeInsight.hint.HintManager; import com.intellij.codeInsight.hint.QuestionAction; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInspection.HintAction; -import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.impl.LaterInvocator; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiJavaFile; -import com.intellij.psi.PsiMember; +import com.intellij.psi.*; import com.intellij.psi.util.FileTypeUtils; import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; @@ -79,7 +75,11 @@ public abstract class StaticImportMemberFix implements Inte && !(candidates == null ? candidates = getMembersToImport(false) : candidates).isEmpty() ; } - + + public final List getMembersToImport() { + return getMembersToImport(false); + } + @NotNull protected abstract List getMembersToImport(boolean applicableOnly); public static boolean isExcluded(PsiMember method) { diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java index 70460bfca8ea..d7dea455820a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java @@ -17,11 +17,14 @@ package com.intellij.codeInsight.editorActions; import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.daemon.impl.quickfix.ImportClassFix; +import com.intellij.codeInsight.daemon.impl.quickfix.StaticImportConstantFix; +import com.intellij.codeInsight.daemon.impl.quickfix.StaticImportMethodFix; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -103,10 +106,10 @@ public class JavaCopyPasteReferenceProcessor extends CopyPasteReferenceProcessor } } - if (CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY) { + if (CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY || + CodeInsightSettings.getInstance().ADD_MEMBER_IMPORTS_ON_THE_FLY) { for (int i = 0; i < refs.length; i++) { - PsiJavaCodeReferenceElement ref = refs[i]; - if (ref != null && new ImportClassFix(ref).getClassesToImport().size() <= 1) { + if (isUnambiguous(refs[i])) { refs[i] = null; } } @@ -115,6 +118,23 @@ public class JavaCopyPasteReferenceProcessor extends CopyPasteReferenceProcessor return refs; } + private static boolean isUnambiguous(@Nullable PsiJavaCodeReferenceElement ref) { + if (ref == null) return false; + + PsiElement parent = ref.getParent(); + if (parent instanceof PsiMethodCallExpression) { + return CodeInsightSettings.getInstance().ADD_MEMBER_IMPORTS_ON_THE_FLY && + new StaticImportMethodFix((PsiMethodCallExpression)parent).getMembersToImport().size() <= 1; + } + + int constCount = new StaticImportConstantFix(ref).getMembersToImport().size(); + int classCount = new ImportClassFix(ref).getClassesToImport().size(); + if (constCount + classCount > 1) return false; + if (constCount + classCount == 0) return true; + return constCount == 1 ? CodeInsightSettings.getInstance().ADD_MEMBER_IMPORTS_ON_THE_FLY + : CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY; + } + @Override protected void restoreReferences(ReferenceData[] referenceData, PsiJavaCodeReferenceElement[] refs) { diff --git a/java/java-impl/src/com/intellij/ide/actions/CreateModuleInfoAction.java b/java/java-impl/src/com/intellij/ide/actions/CreateModuleInfoAction.java index 429487ca4e52..ebc24ac743f7 100644 --- a/java/java-impl/src/com/intellij/ide/actions/CreateModuleInfoAction.java +++ b/java/java-impl/src/com/intellij/ide/actions/CreateModuleInfoAction.java @@ -52,7 +52,7 @@ public class CreateModuleInfoAction extends CreateFromTemplateActionBase { DataContext ctx = e.getDataContext(); boolean available = Optional.ofNullable(LangDataKeys.IDE_VIEW.getData(ctx)) .map(view -> getTargetDirectory(ctx, view)) - .filter(dir -> JavaDirectoryService.getInstance().isSourceRoot(dir) && PsiUtil.isLanguageLevel9OrHigher(dir)) + .filter(PsiUtil::isLanguageLevel9OrHigher) .map(ModuleUtilCore::findModuleForPsiElement) .map(module -> FilenameIndex.getVirtualFilesByName(module.getProject(), MODULE_INFO_FILE, module.getModuleScope(false)).isEmpty()) .orElse(false); @@ -63,7 +63,15 @@ public class CreateModuleInfoAction extends CreateFromTemplateActionBase { @Override protected PsiDirectory getTargetDirectory(DataContext dataContext, IdeView view) { PsiDirectory[] directories = view.getDirectories(); - return directories.length == 1 ? directories[0] : null; + if (directories.length == 1) { + PsiDirectory directory = directories[0]; + JavaDirectoryService service = JavaDirectoryService.getInstance(); + if (service.isSourceRoot(directory) && service.getPackage(directory) != null) { + return directory; + } + } + + return null; } @Override diff --git a/java/java-impl/src/com/intellij/javadoc/JavadocHelper.java b/java/java-impl/src/com/intellij/javadoc/JavadocHelper.java index 9d192a1fecb4..b96d77cac98f 100644 --- a/java/java-impl/src/com/intellij/javadoc/JavadocHelper.java +++ b/java/java-impl/src/com/intellij/javadoc/JavadocHelper.java @@ -107,16 +107,15 @@ public class JavadocHelper { } final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getInstance(psiFile.getProject()).getCurrentSettings(); - final int indentSize = codeStyleSettings.getIndentSize(psiFile.getFileType()); int column; if (codeStyleSettings.JD_ALIGN_PARAM_COMMENTS) { column = Math.max(descriptionStartColumn, parameterNameEndColumn); if (column <= parameterNameEndColumn) { - column = parameterNameEndColumn + indentSize; + column = parameterNameEndColumn + 1; } } else { - column = anchor.parameterNameEndPosition.column + indentSize; + column = anchor.parameterNameEndPosition.column + 1; } return new LogicalPosition(anchor.parameterNameEndPosition.line, column); } diff --git a/java/java-tests/testData/projectView/contentRootUnderExcluded/B.txt b/java/java-tests/testData/projectView/contentRootUnderExcluded/B.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/java/java-tests/testData/projectView/contentRootUnderExcluded/exc/excluded.txt b/java/java-tests/testData/projectView/contentRootUnderExcluded/exc/excluded.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/java/java-tests/testData/projectView/contentRootUnderExcluded/exc/gen/A.java b/java/java-tests/testData/projectView/contentRootUnderExcluded/exc/gen/A.java new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/java/java-tests/testSrc/com/intellij/projectView/ProjectTreeStructureTest.java b/java/java-tests/testSrc/com/intellij/projectView/ProjectTreeStructureTest.java index 46fb031dd4bd..5eecadf0d209 100644 --- a/java/java-tests/testSrc/com/intellij/projectView/ProjectTreeStructureTest.java +++ b/java/java-tests/testSrc/com/intellij/projectView/ProjectTreeStructureTest.java @@ -142,20 +142,44 @@ public class ProjectTreeStructureTest extends BaseProjectViewTestCase { ModuleManagerImpl.getInstanceImpl(myProject).setModuleGroupPath(module, new String[]{"modules"}); PsiTestUtil.addContentRoot(module, mainModuleRoot.findFileByRelativePath("src/com/package1/p2/p3")); - TestProjectTreeStructure structure = new TestProjectTreeStructure(myProject, getTestRootDisposable()); - structure.setShowLibraryContents(false); + myStructure.setShowLibraryContents(false); + myStructure.hideExcludedFiles(); - String structureContent = PlatformTestUtil.print(structure, structure.getRootElement(), 0, null, 10, ' ', myPrintInfo).toString(); + assertStructureEqual("Project\n" + + " nested_module.iml\n" + + " noDuplicateModules\n" + + " src\n" + + " com\n" + + " package1\n" + + " Test.java\n" + + " testNoDuplicateModules.iml\n"); + } - Assert.assertFalse(structureContent.contains("modules")); - assertEquals("Project\n" + - " noDuplicateModules\n" + - " src\n" + - " com\n" + - " package1\n" + - " Test.java\n" + - " nested_module.iml\n" + - " testNoDuplicateModules.iml\n", - structureContent); + public void testContentRootUnderExcluded() { + VirtualFile mainModuleRoot = ModuleRootManager.getInstance(myModule).getContentRoots()[0]; + + PsiTestUtil.addExcludedRoot(myModule, mainModuleRoot.findFileByRelativePath("exc")); + + PsiTestUtil.addContentRoot(myModule, mainModuleRoot.findFileByRelativePath("exc/gen")); + + myStructure.setShowLibraryContents(false); + + assertStructureEqual("Project\n" + + " contentRootUnderExcluded\n" + + " B.txt\n" + + " exc\n" + + " excluded.txt\n" + + " gen\n" + + " A.java\n" + + " testContentRootUnderExcluded.iml\n"); + + myStructure.hideExcludedFiles(); + assertStructureEqual("Project\n" + + " Module\n" + + " contentRootUnderExcluded\n" + + " B.txt\n" + + " gen\n" + + " A.java\n" + + " testContentRootUnderExcluded.iml\n"); } } diff --git a/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java b/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java index 70fec7bcf19f..0c6d1f8fa17d 100644 --- a/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java +++ b/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java @@ -65,9 +65,17 @@ public abstract class BaseProjectViewTestCase extends TestSourceBasedTestCase { return myStructure; } - private void assertStructureEqual(PsiDirectory root, String expected, int maxRowCount, AbstractTreeStructure structure) { + private void assertStructureEqual(PsiDirectory root, String expected, int maxRowCount, AbstractProjectTreeStructure structure) { assertNotNull(root); - PsiDirectoryNode rootNode = new PsiDirectoryNode(myProject, root, (ViewSettings)structure); + PsiDirectoryNode rootNode = new PsiDirectoryNode(myProject, root, structure); + assertStructureEqual(expected, maxRowCount, rootNode); + } + + protected void assertStructureEqual(String expected) { + assertStructureEqual(expected, -1, myStructure.getRootElement()); + } + + private void assertStructureEqual(String expected, int maxRowCount, Object rootNode) { ProjectViewTestUtil.assertStructureEqual(myStructure, expected, maxRowCount, PlatformTestUtil.createComparator(myPrintInfo), rootNode, myPrintInfo); } diff --git a/jps/jps-builders/src/org/jetbrains/jps/ProjectPaths.java b/jps/jps-builders/src/org/jetbrains/jps/ProjectPaths.java index 3fef298f8819..4d21510ad72b 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/ProjectPaths.java +++ b/jps/jps-builders/src/org/jetbrains/jps/ProjectPaths.java @@ -74,9 +74,6 @@ public class ProjectPaths { else if (classpathPart == ClasspathPart.AFTER_JDK) { enumerator = enumerator.satisfying(new AfterJavaSdkItemFilter(module)); } - else if (classpathPart == ClasspathPart.MODULE_PATH) { - enumerator = enumerator.satisfying(new ModuleSourceElementsFilter()); - } JpsJavaDependenciesRootsEnumerator rootsEnumerator = enumerator.classes(); if (excludeMainModuleOutput) { rootsEnumerator = rootsEnumerator.withoutSelfModuleOutput(); @@ -181,7 +178,7 @@ public class ProjectPaths { return StringUtil.isEmpty(sourceDirName)? outputDir : new File(outputDir, sourceDirName); } - private enum ClasspathPart {WHOLE, BEFORE_JDK, AFTER_JDK, MODULE_PATH} + private enum ClasspathPart {WHOLE, BEFORE_JDK, AFTER_JDK} private static class BeforeJavaSdkItemFilter implements Condition { private JpsModule myModule; @@ -220,13 +217,4 @@ public class ProjectPaths { return mySdkFound; } } - - private static class ModuleSourceElementsFilter implements Condition { - private ModuleSourceElementsFilter() { } - - @Override - public boolean value(JpsDependencyElement dependency) { - return dependency instanceof JpsModuleDependency || dependency instanceof JpsModuleSourceDependency; - } - } } \ No newline at end of file diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/artifacts/ArtifactBuildTaskProvider.java b/jps/jps-builders/src/org/jetbrains/jps/builders/artifacts/ArtifactBuildTaskProvider.java index 5d0ff6cc85c6..84972eb29617 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/artifacts/ArtifactBuildTaskProvider.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/artifacts/ArtifactBuildTaskProvider.java @@ -22,6 +22,10 @@ import org.jetbrains.jps.model.artifact.JpsArtifact; import java.util.List; /** + * Allows to perform additional tasks when artifacts are built. Implementations of this class are registered as Java services, by creating + * a file META-INF/services/org.jetbrains.jps.builders.artifacts.ArtifactBuildTaskProvider containing the qualified name of your + * implementation class. + * * @author nik */ public abstract class ArtifactBuildTaskProvider { @@ -38,6 +42,13 @@ public abstract class ArtifactBuildTaskProvider { } } + /** + * Returns list of tasks which need to be executed during {@code buildPhase} when {@code artifact} is building. Firstly tasks returned for + * {@link ArtifactBuildPhase#PRE_PROCESSING PRE_PROCESSING} are executed, then files specified in the artifact layout are copied to the output directory. + * If all files in the artifact output were up to date, i.e. no copying was performed, the build finishes. Otherwise all tasks returned for + * {@link ArtifactBuildPhase#FINISHING_BUILD FINISHING_BUILD} are executed and then all tasks returned for + * {@link ArtifactBuildPhase#POST_PROCESSING POST_PROCESSING} are executed. + */ @NotNull public abstract List createArtifactBuildTasks(@NotNull JpsArtifact artifact, @NotNull ArtifactBuildPhase buildPhase); } diff --git a/native/WinLauncher/WinLauncher/WinLauncher.cpp b/native/WinLauncher/WinLauncher/WinLauncher.cpp index 9399e9391b75..373fc7dce30b 100644 --- a/native/WinLauncher/WinLauncher/WinLauncher.cpp +++ b/native/WinLauncher/WinLauncher/WinLauncher.cpp @@ -900,7 +900,8 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, return 0; } - if (!CheckSingleInstance()) return 1; + //it's OK to return 0 here, because the control is transferred to the first instance + if (!CheckSingleInstance()) return 0; if (nativesplash = wcsstr(lpCmdLine, _T("/nativesplash")) != NULL) StartSplashProcess(); diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java b/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java index 22a1c4a067a3..4df677907bd0 100644 --- a/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java +++ b/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java @@ -344,6 +344,10 @@ public class RefManagerImpl extends RefManager { public void inspectionReadActionFinished() { myIsInProcess = false; if (myScope != null) myScope.invalidate(); + + synchronized (myRefTable) { + mySortedRefs = null; + } } public void startOfflineView() { diff --git a/platform/diff-impl/src/com/intellij/diff/contents/DiffPsiFileType.java b/platform/diff-impl/src/com/intellij/diff/contents/DiffPsiFileType.java index 83d0ee6f84fe..c5c6b29f14eb 100644 --- a/platform/diff-impl/src/com/intellij/diff/contents/DiffPsiFileType.java +++ b/platform/diff-impl/src/com/intellij/diff/contents/DiffPsiFileType.java @@ -85,13 +85,6 @@ public class DiffPsiFileType extends LanguageFileType implements FileTypeIdentif } - public static class TypeFactory extends FileTypeFactory { - @Override - public void createFileTypes(@NotNull FileTypeConsumer consumer) { - consumer.consume(INSTANCE); - } - } - public static class Substitutor extends LanguageSubstitutor { @Nullable @Override diff --git a/platform/diff-impl/src/com/intellij/diff/tools/holders/TextEditorHolder.java b/platform/diff-impl/src/com/intellij/diff/tools/holders/TextEditorHolder.java index 9971ef08d351..8172e35d4640 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/holders/TextEditorHolder.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/holders/TextEditorHolder.java @@ -19,9 +19,13 @@ import com.intellij.diff.DiffContext; import com.intellij.diff.contents.DiffContent; import com.intellij.diff.contents.DocumentContent; import com.intellij.diff.util.DiffUtil; +import com.intellij.ide.DataManager; import com.intellij.openapi.editor.EditorFactory; import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.registry.Registry; +import com.intellij.ui.components.panels.Wrapper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -30,9 +34,19 @@ import java.awt.event.FocusListener; public class TextEditorHolder extends EditorHolder { @NotNull protected final EditorEx myEditor; + @NotNull protected final Wrapper myPanel; - public TextEditorHolder(@NotNull EditorEx editor) { + public TextEditorHolder(@Nullable Project project, @NotNull EditorEx editor) { myEditor = editor; + myPanel = new Wrapper(myEditor.getComponent()); + + DataManager.registerDataProvider(myPanel, (dataId) -> { + if (project != null && !project.isDisposed() && Registry.is("diff.enable.psi.highlighting")) { + final Object o = FileEditorManager.getInstance(project).getData(dataId, editor, editor.getCaretModel().getCurrentCaret()); + if (o != null) return o; + } + return null; + }); } @NotNull @@ -48,7 +62,7 @@ public class TextEditorHolder extends EditorHolder { @NotNull @Override public JComponent getComponent() { - return myEditor.getComponent(); + return myPanel; } @Override @@ -70,7 +84,7 @@ public class TextEditorHolder extends EditorHolder { public static TextEditorHolder create(@Nullable Project project, @NotNull DocumentContent content) { EditorEx editor = DiffUtil.createEditor(content.getDocument(), project, false, true); DiffUtil.configureEditor(editor, content, project); - return new TextEditorHolder(editor); + return new TextEditorHolder(project, editor); } public static class TextEditorHolderFactory extends EditorHolderFactory { diff --git a/platform/diff-impl/src/com/intellij/diff/tools/util/side/TwosideTextDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/util/side/TwosideTextDiffViewer.java index d7750be9e7b6..4b97639f734b 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/util/side/TwosideTextDiffViewer.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/util/side/TwosideTextDiffViewer.java @@ -354,10 +354,6 @@ public abstract class TwosideTextDiffViewer extends TwosideDiffViewer s) { - document.deleteString(s, e); - } - final Project project = file.getProject(); - PsiDocumentManager.getInstance(project).commitAllDocuments(); + if (!myInfo.toMove.equals(myInfo.toMove2)) { // some movers (e.g. PyStatementMover) perform actual moving inside beforeMove/afterMove + final int start = StatementUpDownMover.getLineStartSafeOffset(document, myInfo.toMove.startLine); + final int end = StatementUpDownMover.getLineStartSafeOffset(document, myInfo.toMove.endLine); + String textToInsert = document.getCharsSequence().subSequence(start, end).toString(); + if (!StringUtil.endsWithChar(textToInsert,'\n')) textToInsert += '\n'; - // Swap fold regions status if necessary. - if (topRegion != null && bottomRegion != null) { - CodeFoldingManager.getInstance(project).updateFoldRegions(editor); - editor.getFoldingModel().runBatchFoldingOperation(() -> { - FoldRegion newTopRegion = findTopLevelRegionInRange(editor, myInfo.range1); - if (newTopRegion != null) { - newTopRegion.setExpanded(bottomRegion.isExpanded()); - } + final int start2 = document.getLineStartOffset(myInfo.toMove2.startLine); + final int end2 = StatementUpDownMover.getLineStartSafeOffset(document,myInfo.toMove2.endLine); + String textToInsert2 = document.getCharsSequence().subSequence(start2, end2).toString(); + if (!StringUtil.endsWithChar(textToInsert2,'\n')) textToInsert2 += '\n'; - FoldRegion newBottomRegion = findTopLevelRegionInRange(editor, myInfo.range2); - if (newBottomRegion != null) { - newBottomRegion.setExpanded(topRegion.isExpanded()); - } - }); + TextRange range = new TextRange(start, end); + TextRange range2 = new TextRange(start2, end2); + if (range.intersectsStrict(range2) && !range.equals(range2)) { + LOGGER.error("Wrong move ranges requested by " + myMover, + new Attachment("ranges.txt", + start + ":" + end + "(" + textToInsert + ")\n" + start2 + ":" + end2 + "(" + textToInsert2 + ")")); + return; + } + + myInfo.range1 = document.createRangeMarker(start, end); + myInfo.range2 = document.createRangeMarker(start2, end2); + if (myInfo.range1.getStartOffset() < myInfo.range2.getStartOffset()) { + myInfo.range1.setGreedyToLeft(true); + myInfo.range1.setGreedyToRight(false); + myInfo.range2.setGreedyToLeft(true); + myInfo.range2.setGreedyToRight(true); + } + else { + myInfo.range1.setGreedyToLeft(true); + myInfo.range1.setGreedyToRight(true); + myInfo.range2.setGreedyToLeft(true); + myInfo.range2.setGreedyToRight(false); + } + + final CaretModel caretModel = editor.getCaretModel(); + final int caretRelativePos = caretModel.getOffset() - start; + final SelectionModel selectionModel = editor.getSelectionModel(); + final int selectionStart = selectionModel.getSelectionStart(); + final int selectionEnd = selectionModel.getSelectionEnd(); + final boolean hasSelection = selectionModel.hasSelection(); + + // to prevent flicker + caretModel.moveToOffset(0); + + // There is a possible case that the user performs, say, method move. It's also possible that one (or both) of moved methods + // are folded. We want to preserve their states then. The problem is that folding processing is based on PSI element pointers + // and the pointers behave as following during move up/down: + // method1() {} + // method2() {} + // Pointer for the fold region from method1 points to 'method2()' now and vice versa (check range markers processing on + // document change for further information). I.e. information about fold regions statuses holds the data swapped for + // 'method1' and 'method2'. Hence, we want to apply correct 'collapsed' status. + final FoldRegion topRegion = findTopLevelRegionInRange(editor, myInfo.range1); + final FoldRegion bottomRegion = findTopLevelRegionInRange(editor, myInfo.range2); + + document.insertString(myInfo.range1.getStartOffset(), textToInsert2); + document.deleteString(myInfo.range1.getStartOffset()+textToInsert2.length(), myInfo.range1.getEndOffset()); + + document.insertString(myInfo.range2.getStartOffset(), textToInsert); + int s = myInfo.range2.getStartOffset() + textToInsert.length(); + int e = myInfo.range2.getEndOffset(); + if (e > s) { + document.deleteString(s, e); + } + + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + // Swap fold regions status if necessary. + if (topRegion != null && bottomRegion != null) { + CodeFoldingManager.getInstance(project).updateFoldRegions(editor); + editor.getFoldingModel().runBatchFoldingOperation(() -> { + FoldRegion newTopRegion = findTopLevelRegionInRange(editor, myInfo.range1); + if (newTopRegion != null) { + newTopRegion.setExpanded(bottomRegion.isExpanded()); + } + + FoldRegion newBottomRegion = findTopLevelRegionInRange(editor, myInfo.range2); + if (newBottomRegion != null) { + newBottomRegion.setExpanded(topRegion.isExpanded()); + } + }); + } + + if (hasSelection) { + restoreSelection(editor, selectionStart, selectionEnd, start, end, myInfo.range2.getStartOffset()); + } + + caretModel.moveToOffset(myInfo.range2.getStartOffset() + caretRelativePos); } - - if (hasSelection) { - restoreSelection(editor, selectionStart, selectionEnd, start, end, myInfo.range2.getStartOffset()); - } - - caretModel.moveToOffset(myInfo.range2.getStartOffset() + caretRelativePos); myMover.afterMove(editor, file, myInfo, myIsDown); PsiDocumentManager.getInstance(project).commitDocument(document); if (myInfo.indentTarget) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java index c2cb9fc29874..de1b87b9e592 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java @@ -19,6 +19,7 @@ package com.intellij.codeInsight.navigation; import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.TargetElementUtil; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.DumbService; @@ -68,7 +69,7 @@ public class ImplementationSearcher { if (elements.length > 0) { if (!includeSelfAlways) return filterElements(element, elements, offset); final PsiElement[] all; - if (element.getTextRange() != null) { + if (ReadAction.compute(() -> element.getTextRange()) != null) { all = new PsiElement[elements.length + 1]; all[0] = element; System.arraycopy(elements, 0, all, 1, elements.length); diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchAgainAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchAgainAction.java index 65403b76b9a5..31933bc613f8 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/SearchAgainAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchAgainAction.java @@ -19,17 +19,13 @@ package com.intellij.ide.actions; import com.intellij.find.FindManager; import com.intellij.find.FindUtil; import com.intellij.ide.IdeBundle; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.TextEditor; import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiDocumentManager; public class SearchAgainAction extends AnAction implements DumbAware { diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchBackAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchBackAction.java index 978471cef90f..3676234bdccf 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/SearchBackAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchBackAction.java @@ -19,16 +19,12 @@ package com.intellij.ide.actions; import com.intellij.find.FindManager; import com.intellij.find.FindUtil; import com.intellij.ide.IdeBundle; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.TextEditor; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiDocumentManager; public class SearchBackAction extends AnAction implements DumbAware { diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkAsContentRootAction.kt b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkAsContentRootAction.kt new file mode 100644 index 000000000000..2228bb399437 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkAsContentRootAction.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.projectView.actions + +import com.intellij.ide.projectView.impl.ProjectRootsUtil +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.actionSystem.CommonDataKeys +import com.intellij.openapi.project.DumbAwareAction +import com.intellij.openapi.roots.ModuleRootManager +import com.intellij.openapi.roots.ProjectRootManager + +/** + * @author nik + */ +class MarkAsContentRootAction : DumbAwareAction() { + override fun update(e: AnActionEvent) { + val files = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY) + val module = MarkRootActionBase.getModule(e, files) + if (module == null || files == null) { + e.presentation.isEnabledAndVisible = false + return + } + val fileIndex = ProjectRootManager.getInstance(module.project).fileIndex + e.presentation.isEnabledAndVisible = files.all { + it.isDirectory && fileIndex.isExcluded(it) && ProjectRootsUtil.findExcludeFolder(module, it) == null + } + } + + override fun actionPerformed(e: AnActionEvent) { + val files = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY) ?: return + val module = MarkRootActionBase.getModule(e, files) ?: return + val model = ModuleRootManager.getInstance(module).modifiableModel + files.forEach { + model.addContentEntry(it) + } + MarkRootActionBase.commitModel(module, model) + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootActionBase.java b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootActionBase.java index 4e7683e180b5..0c5d26fdaf15 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootActionBase.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootActionBase.java @@ -77,6 +77,10 @@ public abstract class MarkRootActionBase extends DumbAwareAction { modifyRoots(file, entry); } } + commitModel(module, model); + } + + static void commitModel(@NotNull Module module, ModifiableRootModel model) { DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, () -> ApplicationManager.getApplication().runWriteAction(() -> { model.commit(); @@ -148,7 +152,7 @@ public abstract class MarkRootActionBase extends DumbAwareAction { } @Nullable - private static Module getModule(@NotNull AnActionEvent e, @Nullable VirtualFile[] files) { + static Module getModule(@NotNull AnActionEvent e, @Nullable VirtualFile[] files) { if (files == null) return null; Module module = e.getData(LangDataKeys.MODULE); if (module == null) { 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 127d4a64a2ff..d2f584560bb7 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 @@ -42,6 +42,7 @@ import com.intellij.psi.*; import com.intellij.psi.search.PsiElementProcessor; import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.FontUtil; +import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -212,6 +213,19 @@ public class ProjectViewDirectoryHelper { return topLevelContentRoots; } + public List getTopLevelModuleRoots(Module module, ViewSettings settings) { + return ContainerUtil.filter(ModuleRootManager.getInstance(module).getContentRoots(), root -> { + if (!shouldBeShown(root, settings)) return false; + VirtualFile parent = root.getParent(); + if (parent == null) return true; + DirectoryInfo info = myIndex.getInfoForFile(parent); + if (!module.equals(info.getModule())) return true; + //show inner content root separately only if it won't be shown under outer content root + return info.isExcluded() && !shouldShowExcludedFiles(settings); + }); + } + + private static boolean isFileInContent(ProjectFileIndex index, VirtualFile file) { while (file != null) { if (index.isInContent(file)) { @@ -260,12 +274,11 @@ public class ProjectViewDirectoryHelper { private boolean shouldBeShown(VirtualFile dir, ViewSettings settings) { DirectoryInfo directoryInfo = myIndex.getInfoForFile(dir); - if (directoryInfo.isInProject()) return true; + return directoryInfo.isInProject() || shouldShowExcludedFiles(settings) && directoryInfo.isExcluded(); + } - if (!Registry.is("ide.hide.excluded.files") && settings instanceof ProjectViewSettings && ((ProjectViewSettings)settings).isShowExcludedFiles()) { - return directoryInfo.isExcluded(); - } - return false; + private static boolean shouldShowExcludedFiles(ViewSettings settings) { + return !Registry.is("ide.hide.excluded.files") && settings instanceof ProjectViewSettings && ((ProjectViewSettings)settings).isShowExcludedFiles(); } // used only for non-flatten packages mode diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewModuleNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewModuleNode.java index 1b51e33c0353..9da0e81d4765 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewModuleNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewModuleNode.java @@ -46,15 +46,11 @@ public class ProjectViewModuleNode extends AbstractModuleNode { if (module == null || module.isDisposed()) { // module has been disposed return Collections.emptyList(); } - ModuleRootManager rootManager = ModuleRootManager.getInstance(module); - ModuleFileIndex moduleFileIndex = rootManager.getFileIndex(); - final VirtualFile[] contentRoots = rootManager.getContentRoots(); - final List children = new ArrayList<>(contentRoots.length + 1); + final List contentRoots = ProjectViewDirectoryHelper.getInstance(myProject).getTopLevelModuleRoots(module, getSettings()); + final List children = new ArrayList<>(contentRoots.size()); final PsiManager psiManager = PsiManager.getInstance(module.getProject()); for (final VirtualFile contentRoot : contentRoots) { - if (!moduleFileIndex.isInContent(contentRoot)) continue; - if (contentRoot.isDirectory()) { PsiDirectory directory = psiManager.findDirectory(contentRoot); if (directory != null) { @@ -68,12 +64,6 @@ public class ProjectViewModuleNode extends AbstractModuleNode { } } } - - /* - if (getSettings().isShowLibraryContents()) { - children.add(new LibraryGroupNode(getProject(), new LibraryGroupElement(getValue()), getSettings())); - } - */ return children; } diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java index 2e41e8db07e1..f89abd9b0b33 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java @@ -22,7 +22,6 @@ import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.io.FileUtil; @@ -125,9 +124,9 @@ public class ProjectViewProjectNode extends AbstractProjectNode { @Override protected AbstractTreeNode createModuleGroup(final Module module) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { - final VirtualFile[] roots = ModuleRootManager.getInstance(module).getContentRoots(); - if (roots.length == 1) { - final PsiDirectory psi = PsiManager.getInstance(myProject).findDirectory(roots[0]); + List roots = ProjectViewDirectoryHelper.getInstance(myProject).getTopLevelModuleRoots(module, getSettings()); + if (roots.size() == 1) { + final PsiDirectory psi = PsiManager.getInstance(myProject).findDirectory(roots.get(0)); if (psi != null) { return new PsiDirectoryNode(myProject, psi, getSettings()); } diff --git a/java/java-impl/src/com/intellij/reporting/ReportMissingOrExcessiveInlineHint.kt b/platform/lang-impl/src/com/intellij/reporting/ReportExcessiveInlineHint.kt similarity index 95% rename from java/java-impl/src/com/intellij/reporting/ReportMissingOrExcessiveInlineHint.kt rename to platform/lang-impl/src/com/intellij/reporting/ReportExcessiveInlineHint.kt index 3e06f1ae1231..d18d9dc48230 100644 --- a/java/java-impl/src/com/intellij/reporting/ReportMissingOrExcessiveInlineHint.kt +++ b/platform/lang-impl/src/com/intellij/reporting/ReportExcessiveInlineHint.kt @@ -31,13 +31,13 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.util.TextRange import java.io.File -class ReportMissingOrExcessiveInlineHint : AnAction() { +class ReportExcessiveInlineHint : AnAction() { - private val text = "Report Missing or Excessive Inline Hint" + private val text = "Report Excessive Inline Hint" private val description = "Text line at caret will be anonymously reported to our servers" companion object { - private val LOG = Logger.getInstance(ReportMissingOrExcessiveInlineHint::class.java) + private val LOG = Logger.getInstance(ReportExcessiveInlineHint::class.java) } init { diff --git a/platform/platform-impl/src/com/intellij/ui/ComboBoxCompositeEditor.java b/platform/platform-impl/src/com/intellij/ui/ComboBoxCompositeEditor.java index 9cba1bb1351c..510e6bd8a5bb 100644 --- a/platform/platform-impl/src/com/intellij/ui/ComboBoxCompositeEditor.java +++ b/platform/platform-impl/src/com/intellij/ui/ComboBoxCompositeEditor.java @@ -21,6 +21,7 @@ import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.util.function.BiConsumer; +import java.util.function.BiFunction; import static java.awt.GridBagConstraints.CENTER; @@ -41,12 +42,18 @@ public class ComboBoxCompositeEditor extends JPanel imp } private BiConsumer myOnSetItemHandler = null; + private BiFunction myOnGetItemHandler = null; public ComboBoxCompositeEditor onSetItem (BiConsumer onSetItemHandler) { myOnSetItemHandler = onSetItemHandler; return this; } + public ComboBoxCompositeEditor onGetItem (BiFunction onGetItemHandler) { + myOnGetItemHandler = onGetItemHandler; + return this; + } + public interface EditorComponent { void setItem(I anObject); I getItem(); @@ -75,10 +82,14 @@ public class ComboBoxCompositeEditor extends JPanel imp abstract void addActionListener(F component, ActionListener l) ; abstract void removeActionListener(F component, ActionListener l) ; + + abstract I getItem(F component, I item); } private ComboBoxCompositeEditorStrategy editorTextFieldStrategy = new ComboBoxCompositeEditorStrategy () { - BiConsumer defaultOnSetHandler = (anObject, component) -> (component).setText((anObject == null) ? "" : anObject.toString()); + + BiConsumer defaultOnSetHandler = (anObject, component) -> component.setText((anObject == null) ? "" : anObject.toString()); + public void setItem(F component, I anObject) { if (myOnSetItemHandler == null) { defaultOnSetHandler.accept(anObject, (EditorTextField)component); @@ -87,6 +98,14 @@ public class ComboBoxCompositeEditor extends JPanel imp } } + public I getItem(F component, I anObject) { + if (myOnGetItemHandler == null) { + return anObject; + } else { + return myOnGetItemHandler.apply(anObject, component); + } + } + public void selectAll(JComponent component) { ((EditorTextField)component).selectAll(); } @@ -100,7 +119,7 @@ public class ComboBoxCompositeEditor extends JPanel imp } }; - private ComboBoxCompositeEditorStrategy jTextFieldStrategy = new ComboBoxCompositeEditorStrategy(){ + private ComboBoxCompositeEditorStrategy jTextFieldStrategy = new ComboBoxCompositeEditorStrategy() { BiConsumer defaultOnSetHandler = (anObject, component) -> component.setText((anObject ==null) ? "" : anObject.toString()); @@ -112,6 +131,14 @@ public class ComboBoxCompositeEditor extends JPanel imp } } + public I getItem(F component, I anObject) { + if (myOnGetItemHandler == null) { + return anObject; + } else { + return myOnGetItemHandler.apply(anObject, component); + } + } + public void selectAll(JComponent component) { ((JTextField)component).selectAll(); } @@ -162,7 +189,7 @@ public class ComboBoxCompositeEditor extends JPanel imp } public I getItem() { - return myItem; + return strategy.getItem((F)components[focusableComponentIndex], myItem); } @Override diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index 4bb6bb83d24c..fcd5d571cb2e 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -416,6 +416,8 @@ action.ShowSiblings.text=Show Siblings action.ShowSiblings.description=Show a popup window with the symbol siblings content action.ParameterInfo.text=_Parameter Info action.ParameterInfo.description=Show parameters of the method call at caret +action.ToggleInlineHintsAction.text=Toggle parameter name hints +action.ToggleInlineHintsAction.description=Toggle parameter name hints action.ExpressionTypeInfo.text=_Expression Type action.ExpressionTypeInfo.description=Show type of the selected expression action.EditorContextInfo.text=_Context Info @@ -1474,6 +1476,8 @@ group.Vcs.Browse.text=Browse VCS Repository action.Graph.print.reset=Reset action.MarkExcludeRoot.text=Excluded action.UnmarkRoot.text=Unmark Root +action.MarkAsContentRoot.text=Cancel Exclusion +action.MarkAsContentRoot.description=Cancel exclusion for the selected directory to make its files processable by IDE's actions action.CreateLibraryFromFile.text=Add as Library... action.ImportModuleFromImlFile.text=Import Module action.ImportModuleFromImlFile.description=Import iml file as a module to the project diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index af355de3126a..d295e219fef4 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -107,7 +107,6 @@ - diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index cac3ae55220b..9a2c145584f2 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -298,7 +298,12 @@ - + + + + + + diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/FileIndex.java b/platform/projectModel-api/src/com/intellij/openapi/roots/FileIndex.java index d2182f033471..0d8def9d6273 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/roots/FileIndex.java +++ b/platform/projectModel-api/src/com/intellij/openapi/roots/FileIndex.java @@ -30,7 +30,7 @@ import java.util.Set; */ public interface FileIndex { /** - * Iterates all files and directories in the content. + * Iterates all files and directories under content roots skipping excluded and ignored files and directories. * * @param iterator the iterator receiving the files. * @return false if files processing was stopped ({@link ContentIterator#processFile(VirtualFile)} returned false) @@ -38,8 +38,8 @@ public interface FileIndex { boolean iterateContent(@NotNull ContentIterator iterator); /** - * Iterates all files and directories in the content under directory dir (including the directory itself). - * Does not iterate anything if dir is not in the content. + * Iterates all files and directories in the content under directory dir (including the directory itself) skipping excluded + * and ignored files and directories. Does not iterate anything if dir is not in the content. * * @param dir the directory the contents of which is iterated. * @param iterator the iterator receiving the files. @@ -48,17 +48,14 @@ public interface FileIndex { boolean iterateContentUnderDirectory(@NotNull VirtualFile dir, @NotNull ContentIterator iterator); /** - * Returns true if fileOrDir is a file or directory under a content root of this - * project or module. - * - * @param fileOrDir the file or directory to check. - * @return true if the file or directory belongs to a content root, false otherwise. + * Returns {@code true} if {@code fileOrDir} is a file or directory under a content root of this project or module and not excluded or + * ignored. */ boolean isInContent(@NotNull VirtualFile fileOrDir); /** - * Returns true if file is a source file which belongs to sources of the content. - * (Returns true for both source and test source).

+ * Returns {@code true} if {@code fileOrDir} is a file located under a sources, tests or resources root and not excluded or ignored. + *

* Note that sometimes a file can belong to the content and be a source file but not belong to sources of the content. * This happens if sources of some library are located under the content (so they belong to the project content but not as sources). * @@ -68,16 +65,12 @@ public interface FileIndex { boolean isContentSourceFile(@NotNull VirtualFile file); /** - * Returns true if fileOrDir is a file or directory from the content source. - * (Returns true for both source and test source). - * - * @param fileOrDir the file or directory to check. - * @return true if the file or directory belongs to a source or test source root, false otherwise. + * Returns {@code true} if {@code fileOrDir} is a file or directory located under a sources, tests or resources root and not excluded or ignored. */ boolean isInSourceContent(@NotNull VirtualFile fileOrDir); /** - * Returns true if fileOrDir is a file or directory from the test content source + * Returns true if {@code fileOrDir} is a file or directory located under a test sources or resources root and not excluded or ignored. *

* Use this method when you really need to check whether the file is under test roots according to project configuration. *

@@ -92,10 +85,7 @@ public interface FileIndex { boolean isInTestSourceContent(@NotNull VirtualFile fileOrDir); /** - * Returns true if fileOrDir is a file or directory from the source root which have - * - * @param fileOrDir the file or directory to check. - * @return true if the file or directory belongs to a source root of one of specified types, false otherwise + * Returns {@code true} if {@code fileOrDir} is a file or directory located under a source root of type from {@code rootTypes} set and not excluded or ignored */ boolean isUnderSourceRootOfType(@NotNull VirtualFile fileOrDir, @NotNull Set> rootTypes); } diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java index 8b3de586c61e..aa6a5aa35f5d 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java @@ -712,7 +712,10 @@ public class SMTestRunnerResultsForm extends TestResultsPanel private void updateProgressOnTestDone() { int doneTestCount = myFinishedTestCount; // update progress - if (myTotalTestCount != 0 && !isUndefined()) { + if (isUndefined()) { + myStatusLine.setFraction(1.0); + } + else if (myTotalTestCount != 0) { // if total is set myStatusLine.setFraction((double) doneTestCount / myTotalTestCount); } diff --git a/platform/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.java b/platform/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.java index a1bd02b83d5c..eee966b1386b 100644 --- a/platform/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.java +++ b/platform/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.java @@ -15,6 +15,7 @@ */ package com.intellij.projectView; +import com.intellij.ide.projectView.ProjectViewSettings; import com.intellij.ide.projectView.impl.AbstractProjectTreeStructure; import com.intellij.ide.projectView.impl.AbstractProjectViewPSIPane; import com.intellij.openapi.Disposable; @@ -25,7 +26,8 @@ import com.intellij.psi.PsiElement; import com.intellij.testFramework.ProjectViewTestUtil; import org.junit.Assert; -public class TestProjectTreeStructure extends AbstractProjectTreeStructure implements Disposable { +public class TestProjectTreeStructure extends AbstractProjectTreeStructure implements Disposable, ProjectViewSettings { + private boolean myShowExcludedFiles = true; protected boolean myShowMembers = false; protected boolean myHideEmptyMiddlePackages; protected boolean myFlattenPackages; @@ -74,6 +76,11 @@ public class TestProjectTreeStructure extends AbstractProjectTreeStructure imple return myShowLibraryContents; } + @Override + public boolean isShowExcludedFiles() { + return myShowExcludedFiles; + } + @Override public boolean isShowModules() { return true; @@ -91,6 +98,10 @@ public class TestProjectTreeStructure extends AbstractProjectTreeStructure imple myFlattenPackages = flattenPackages; } + public void hideExcludedFiles() { + myShowExcludedFiles = false; + } + public void setShowLibraryContents(boolean showLibraryContents) { myShowLibraryContents = showLibraryContents; } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRenderer.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRenderer.java index ffe43ec4bb99..0591dd7ac0bb 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRenderer.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRenderer.java @@ -37,7 +37,7 @@ import java.util.Map; public class GraphCommitCellRenderer extends ColoredTableCellRenderer { private static final Logger LOG = Logger.getInstance(GraphCommitCellRenderer.class); - private static final int MAX_GRAPH_WIDTH = 10; + private static final int MAX_GRAPH_WIDTH = 6; private static final int VERTICAL_PADDING = JBUI.scale(7); diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/TransformationContext.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/TransformationContext.java index 4f4a924a583f..ddaebc48144e 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/TransformationContext.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/TransformationContext.java @@ -87,6 +87,13 @@ public interface TransformationContext { return getAnnotation(fqn) != null; } + default boolean isInheritor(@NotNull String fqn) { + PsiClass baseClass = getPsiFacade().findClass(fqn, getResolveScope()); + return baseClass != null && isInheritor(baseClass); + } + + boolean isInheritor(@NotNull PsiClass baseClass); + @NotNull Collection findMethodsByName(@NotNull String name, boolean checkBases); diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/TransformationContextImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/TransformationContextImpl.java index 726003266e4e..87b1bc329af5 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/TransformationContextImpl.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/TransformationContextImpl.java @@ -122,6 +122,21 @@ public class TransformationContextImpl implements TransformationContext { return PsiImplUtil.getAnnotation(getCodeClass(), fqn); } + @Override + public boolean isInheritor(@NotNull PsiClass baseClass) { + if (getManager().areElementsEquivalent(getCodeClass(), baseClass)) return false; + if (getCodeClass().isInterface() && !baseClass.isInterface()) return false; + + for (PsiClassType superType : getSuperTypes()) { + PsiClass superClass = superType.resolve(); + if (superClass == null) continue; + if (getManager().areElementsEquivalent(superClass, baseClass)) return true; + if (superClass.isInheritor(baseClass, true)) return true; + } + + return false; + } + @NotNull @Override public Collection findMethodsByName(@NotNull String name, boolean checkBases) { diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index c009d86d4396..cc47620fcd49 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -28,7 +28,7 @@ import com.intellij.injected.editor.VirtualFileWindow; import com.intellij.lang.ASTFactory; import com.intellij.lang.ASTNode; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.application.impl.ApplicationImpl; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorFactory; @@ -862,26 +862,31 @@ public class PyUtil { return result; } + /** + * This method is allowed to be called from any thread, but in general you should not set {@code modal=true} if you're calling it + * from the write action, because in this case {@code function} will be executed right in the current thread (presumably EDT) + * without any progress whatsoever to avoid possible deadlock. + * + * @see ApplicationImpl#runProcessWithProgressSynchronously(Runnable, String, boolean, Project, JComponent, String) + */ public static void runWithProgress(@Nullable Project project, @Nls(capitalization = Nls.Capitalization.Title) @NotNull String title, boolean modal, boolean canBeCancelled, @NotNull final Consumer function) { - ApplicationManager.getApplication().invokeAndWait(() -> { - if (modal) { - ProgressManager.getInstance().run(new Task.Modal(project, title, canBeCancelled) { - @Override - public void run(@NotNull ProgressIndicator indicator) { - function.consume(indicator); - } - }); - } - else { - ProgressManager.getInstance().run(new Task.Backgroundable(project, title, canBeCancelled) { - @Override - public void run(@NotNull ProgressIndicator indicator) { - function.consume(indicator); - } - }); - } - }, ModalityState.current()); + if (modal) { + ProgressManager.getInstance().run(new Task.Modal(project, title, canBeCancelled) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + function.consume(indicator); + } + }); + } + else { + ProgressManager.getInstance().run(new Task.Backgroundable(project, title, canBeCancelled) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + function.consume(indicator); + } + }); + } } /** diff --git a/python/testData/mover/class_afterUp.py b/python/testData/mover/class_afterUp.py index 7864db22ba35..710862786d3c 100644 --- a/python/testData/mover/class_afterUp.py +++ b/python/testData/mover/class_afterUp.py @@ -4,4 +4,4 @@ if condition: class C: pass class B(Exception): - b=1 + b=1 \ No newline at end of file diff --git a/python/testData/mover/lastComment1_afterDown.py b/python/testData/mover/lastComment1_afterDown.py index b6ff87fd824b..4c6a890dbcad 100644 --- a/python/testData/mover/lastComment1_afterDown.py +++ b/python/testData/mover/lastComment1_afterDown.py @@ -3,4 +3,4 @@ def f(): a = 1 else: a = 2 -#comment +#comment \ No newline at end of file diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 7cc48c65c979..2e0249035038 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -1828,9 +1828,6 @@ - - - diff --git a/resources/src/idea/RichPlatformActions.xml b/resources/src/idea/RichPlatformActions.xml index 8b01f1bc4930..f45f64028afc 100644 --- a/resources/src/idea/RichPlatformActions.xml +++ b/resources/src/idea/RichPlatformActions.xml @@ -390,6 +390,7 @@ +