Merge remote-tracking branch 'origin/master'

This commit is contained in:
Roman Shevchenko
2016-10-06 12:13:34 +02:00
46 changed files with 486 additions and 236 deletions
@@ -157,7 +157,7 @@ public class CheckRegExpForm {
myRootPanel.revalidate();
Balloon balloon = JBPopupFactory.getInstance().getParentBalloonFor(myRootPanel);
if (balloon != null) balloon.revalidate();
}, ModalityState.current());
});
}
@TestOnly
@@ -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));
@@ -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<T extends PsiMember> implements Inte
&& !(candidates == null ? candidates = getMembersToImport(false) : candidates).isEmpty()
;
}
public final List<T> getMembersToImport() {
return getMembersToImport(false);
}
@NotNull protected abstract List<T> getMembersToImport(boolean applicableOnly);
public static boolean isExcluded(PsiMember method) {
@@ -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) {
@@ -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
@@ -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);
}
@@ -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");
}
}
@@ -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);
}
@@ -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<JpsDependencyElement> {
private JpsModule myModule;
@@ -220,13 +217,4 @@ public class ProjectPaths {
return mySdkFound;
}
}
private static class ModuleSourceElementsFilter implements Condition<JpsDependencyElement> {
private ModuleSourceElementsFilter() { }
@Override
public boolean value(JpsDependencyElement dependency) {
return dependency instanceof JpsModuleDependency || dependency instanceof JpsModuleSourceDependency;
}
}
}
@@ -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<? extends BuildTask> createArtifactBuildTasks(@NotNull JpsArtifact artifact, @NotNull ArtifactBuildPhase buildPhase);
}
@@ -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();
@@ -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() {
@@ -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
@@ -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<TextEditorHolder> {
@@ -354,10 +354,6 @@ public abstract class TwosideTextDiffViewer extends TwosideDiffViewer<TextEditor
@Override
public Object getData(@NonNls String dataId) {
EditorEx editor = getCurrentEditor();
if (myProject != null && !myProject.isDisposed() && Registry.is("diff.enable.psi.highlighting")) {
final Object o = FileEditorManager.getInstance(myProject).getData(dataId, editor, editor.getCaretModel().getCurrentCaret());
if (o != null) return o;
}
if (DiffDataKeys.CURRENT_EDITOR.is(dataId)) {
return editor;
@@ -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.analysis.actions
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.project.ProjectManager
import com.intellij.psi.PsiManager
class ToggleInlineHintsAction: AnAction() {
override fun update(e: AnActionEvent) {
e.presentation.isEnabled = true
val isShow = EditorSettingsExternalizable.getInstance().isShowParameterNameHints
e.presentation.text = if (isShow) "Hide Parameter Name Hints" else "Show Parameter Name Hints"
}
override fun actionPerformed(e: AnActionEvent) {
val settings = EditorSettingsExternalizable.getInstance()
val before = settings.isShowParameterNameHints
settings.isShowParameterNameHints = !before
ProjectManager.getInstance().openProjects.forEach {
val psiManager = PsiManager.getInstance(it)
val daemonCodeAnalyzer = DaemonCodeAnalyzer.getInstance(it)
val fileEditorManager = FileEditorManager.getInstance(it)
fileEditorManager.selectedFiles.forEach {
psiManager.findFile(it)?.let { daemonCodeAnalyzer.restart(it) }
}
}
}
}
@@ -85,8 +85,9 @@ import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
/**
* @author peter
* Please don't use this class directly from plugins
*/
@Deprecated
public class CompletionProgressIndicator extends ProgressIndicatorBase implements CompletionProcess, Disposable {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.CompletionProgressIndicator");
private final Editor myEditor;
@@ -159,6 +159,12 @@ public class ParameterHintsPresentationManager implements Disposable {
updateState(editor, newText);
}
@Nullable
@Override
public String getContextMenuGroupId() {
return "ParameterNameHints";
}
private void updateState(Editor editor, String text) {
FontMetrics metrics = getFontMetrics(editor).metrics;
startWidth = doCalcWidth(myText, metrics);
@@ -54,96 +54,97 @@ class MoverWrapper {
assert myInfo.toMove2 != null;
myMover.beforeMove(editor, myInfo, myIsDown);
final Document document = editor.getDocument();
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';
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';
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);
}
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) {
@@ -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);
@@ -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 {
@@ -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 {
@@ -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)
}
}
@@ -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) {
@@ -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<VirtualFile> 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
@@ -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<AbstractTreeNode> children = new ArrayList<>(contentRoots.length + 1);
final List<VirtualFile> contentRoots = ProjectViewDirectoryHelper.getInstance(myProject).getTopLevelModuleRoots(module, getSettings());
final List<AbstractTreeNode> 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;
}
@@ -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<VirtualFile> 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());
}
@@ -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 {
@@ -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<I, F extends JComponent> extends JPanel imp
}
private BiConsumer<I, F> myOnSetItemHandler = null;
private BiFunction<I, F, I> myOnGetItemHandler = null;
public ComboBoxCompositeEditor<I, F> onSetItem (BiConsumer<I, F> onSetItemHandler) {
myOnSetItemHandler = onSetItemHandler;
return this;
}
public ComboBoxCompositeEditor<I, F> onGetItem (BiFunction<I, F, I> onGetItemHandler) {
myOnGetItemHandler = onGetItemHandler;
return this;
}
public interface EditorComponent<F, I> {
void setItem(I anObject);
I getItem();
@@ -75,10 +82,14 @@ public class ComboBoxCompositeEditor<I, F extends JComponent> 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<I, EditorTextField> defaultOnSetHandler = (anObject, component) -> (component).setText((anObject == null) ? "" : anObject.toString());
BiConsumer<I, EditorTextField> 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<I, F extends JComponent> 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<I, F extends JComponent> extends JPanel imp
}
};
private ComboBoxCompositeEditorStrategy jTextFieldStrategy = new ComboBoxCompositeEditorStrategy(){
private ComboBoxCompositeEditorStrategy jTextFieldStrategy = new ComboBoxCompositeEditorStrategy() {
BiConsumer<I, JTextField> defaultOnSetHandler = (anObject, component) -> component.setText((anObject ==null) ? "" : anObject.toString());
@@ -112,6 +131,14 @@ public class ComboBoxCompositeEditor<I, F extends JComponent> 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<I, F extends JComponent> extends JPanel imp
}
public I getItem() {
return myItem;
return strategy.getItem((F)components[focusableComponentIndex], myItem);
}
@Override
@@ -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
@@ -107,7 +107,6 @@
<colorAndFontPanelFactory implementation="com.intellij.openapi.diff.impl.settings.DiffColorsPageFactory"/>
<colorAndFontDescriptorProvider implementation="com.intellij.openapi.diff.impl.settings.DiffColorsPageFactory"/>
<fileTypeFactory implementation="com.intellij.diff.contents.DiffPsiFileType$TypeFactory"/>
<lang.substitutor language="TEXT" implementationClass="com.intellij.diff.contents.DiffPsiFileType$Substitutor" order="first"/>
<daemon.highlightInfoFilter implementation="com.intellij.diff.contents.DiffPsiFileType$HighlightFilter"/>
<daemon.intentionActionFilter implementation="com.intellij.diff.contents.DiffPsiFileType$IntentionFilter"/>
@@ -298,7 +298,12 @@
<separator/>
<add-to-group group-id="MainMenu" anchor="after" relative-to-action="GoToMenu"/>
</group>
<group id="ParameterNameHints" popup="true">
<action id="ToggleInlineHintsAction" class="com.intellij.analysis.actions.ToggleInlineHintsAction"/>
<action id="ReportExcessiveInlineHint" class="com.intellij.reporting.ReportExcessiveInlineHint"/>
</group>
<!-- Analyze -->
<action id="SliceBackward" class="com.intellij.slicer.SliceBackwardAction"/>
<action id="SliceForward" class="com.intellij.slicer.SliceForwardAction"/>
@@ -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 <code>dir</code> (including the directory itself).
* Does not iterate anything if <code>dir</code> is not in the content.
* Iterates all files and directories in the content under directory <code>dir</code> (including the directory itself) skipping excluded
* and ignored files and directories. Does not iterate anything if <code>dir</code> 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 <code>fileOrDir</code> 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 <code>file</code> is a source file which belongs to sources of the content.
* (Returns true for both source and test source).<p/>
* Returns {@code true} if {@code fileOrDir} is a file located under a sources, tests or resources root and not excluded or ignored.
* <p/>
* 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 <code>fileOrDir</code> 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 <code>fileOrDir</code> 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.
* <p>
* Use this method when you really need to check whether the file is under test roots according to project configuration.
* <p>
@@ -92,10 +85,7 @@ public interface FileIndex {
boolean isInTestSourceContent(@NotNull VirtualFile fileOrDir);
/**
* Returns true if <code>fileOrDir</code> 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<? extends JpsModuleSourceRootType<?>> rootTypes);
}
@@ -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);
}
@@ -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;
}
@@ -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);
@@ -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<PsiMethod> findMethodsByName(@NotNull String name, boolean checkBases);
@@ -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<PsiMethod> findMethodsByName(@NotNull String name, boolean checkBases) {
+24 -19
View File
@@ -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<ProgressIndicator> 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);
}
});
}
}
/**
+1 -1
View File
@@ -4,4 +4,4 @@ if condition:
class C:
pass
class B(Exception):
b=1
b=1
@@ -3,4 +3,4 @@ def f():
a = 1
else:
a = 2
#comment <caret>
#comment <caret>
-3
View File
@@ -1828,9 +1828,6 @@
<action id="ShowRecentTests" class="com.intellij.testIntegration.ShowRecentTests">
<keyboard-shortcut first-keystroke="control shift SEMICOLON" keymap="$default"/>
</action>
<action id="ReportMissingOrExcessiveInlineHint" class="com.intellij.reporting.ReportMissingOrExcessiveInlineHint">
<add-to-group group-id="EditorPopupMenu"/>
</action>
<action class="com.intellij.execution.testDiscovery.ConfigureTestDiscoveryAction" internal="true" id="TestDiscoveryIndexChooser" text="Choose external test discovery indices">
<add-to-group group-id="Internal" anchor="last"/>
</action>
@@ -390,6 +390,7 @@
<group>
<group id="MarkSourceRootGroup" class="com.intellij.ide.projectView.actions.MarkSourceRootActionGroup"/>
<action id="MarkExcludeRoot" class="com.intellij.ide.projectView.actions.MarkExcludeRootAction" icon="AllIcons.Modules.ExcludeRoot"/>
<action id="MarkAsContentRoot" class="com.intellij.ide.projectView.actions.MarkAsContentRootAction"/>
<action id="UnmarkRoot" class="com.intellij.ide.projectView.actions.UnmarkRootAction"/>
<add-to-group group-id="MarkRootGroup"/>
</group>