mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -118,7 +118,7 @@ public class ImageComponentUI extends ComponentUI {
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
}
|
||||
UIUtil.drawImage(g, renderer, 0, 0, size.width, size.height, ic);
|
||||
UIUtil.drawImage(g, renderer, new Rectangle(0, 0, size.width, size.height), null, ic);
|
||||
|
||||
g2d.setRenderingHints(oldHints);
|
||||
}
|
||||
|
||||
+46
-25
@@ -15,12 +15,14 @@
|
||||
*/
|
||||
package com.intellij.psi.impl.search;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.GlobalSearchScopeUtil;
|
||||
import com.intellij.psi.search.GlobalSearchScopesCore;
|
||||
import com.intellij.psi.search.searches.MethodReferencesSearch;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.CommonProcessors;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.indexing.FileBasedIndex;
|
||||
@@ -32,6 +34,7 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
public class JavaNullMethodArgumentUtil {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.search.JavaNullMethodArgumentUtil");
|
||||
|
||||
public static boolean hasNullArgument(@NotNull PsiMethod method, final int argumentIdx) {
|
||||
final boolean[] result = {false};
|
||||
@@ -47,35 +50,55 @@ public class JavaNullMethodArgumentUtil {
|
||||
if (parameter.getType() instanceof PsiEllipsisType) {
|
||||
return;
|
||||
}
|
||||
final GlobalSearchScope scope = findScopeWhereNullArgumentCanPass(method, argumentIdx);
|
||||
if (scope == null) return;
|
||||
Collection<VirtualFile> candidateFiles = getFilesWithPotentialNullPassingCalls(method, argumentIdx);
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
processCallsWithNullArguments(method, argumentIdx, nullArgumentProcessor, candidateFiles);
|
||||
|
||||
long duration = System.currentTimeMillis() - start;
|
||||
if (duration > 200) {
|
||||
LOG.trace("Long nullable argument search for " + method.getName() + "(" + PsiUtil.getMemberQualifiedName(method) + "): " + duration + "ms, " + candidateFiles.size() + " files");
|
||||
}
|
||||
}
|
||||
|
||||
private static void processCallsWithNullArguments(@NotNull PsiMethod method,
|
||||
int argumentIdx,
|
||||
@NotNull Processor<PsiExpression> nullArgumentProcessor,
|
||||
Collection<VirtualFile> candidateFiles) {
|
||||
if (candidateFiles.isEmpty()) return;
|
||||
|
||||
GlobalSearchScope scope = GlobalSearchScope.filesScope(method.getProject(), candidateFiles);
|
||||
MethodReferencesSearch.search(method, scope, true).forEach(ref -> {
|
||||
final PsiElement psi = ref.getElement();
|
||||
if (psi != null) {
|
||||
final PsiElement parent = psi.getParent();
|
||||
PsiExpressionList argumentList = null;
|
||||
if (parent instanceof PsiCallExpression) {
|
||||
argumentList = ((PsiCallExpression)parent).getArgumentList();
|
||||
}
|
||||
else if (parent instanceof PsiAnonymousClass) {
|
||||
argumentList = ((PsiAnonymousClass)parent).getArgumentList();
|
||||
}
|
||||
if (argumentList != null) {
|
||||
final PsiExpression[] arguments = argumentList.getExpressions();
|
||||
if (argumentIdx < arguments.length) {
|
||||
final PsiExpression argument = arguments[argumentIdx];
|
||||
if (argument instanceof PsiLiteralExpression && PsiKeyword.NULL.equals(argument.getText())) {
|
||||
return nullArgumentProcessor.process(argument);
|
||||
}
|
||||
}
|
||||
}
|
||||
PsiExpression argument = getCallArgument(ref, argumentIdx);
|
||||
if (argument instanceof PsiLiteralExpression && argument.textMatches(PsiKeyword.NULL)) {
|
||||
return nullArgumentProcessor.process(argument);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static GlobalSearchScope findScopeWhereNullArgumentCanPass(@NotNull PsiMethod method, int parameterIndex) {
|
||||
private static PsiExpression getCallArgument(PsiReference ref, int argumentIdx) {
|
||||
PsiExpressionList argumentList = getCallArgumentList(ref.getElement());
|
||||
PsiExpression[] arguments = argumentList == null ? PsiExpression.EMPTY_ARRAY : argumentList.getExpressions();
|
||||
return argumentIdx < arguments.length ? arguments[argumentIdx] : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiExpressionList getCallArgumentList(@Nullable PsiElement psi) {
|
||||
PsiElement parent = psi == null ? null :psi.getParent();
|
||||
if (parent instanceof PsiCallExpression) {
|
||||
return ((PsiCallExpression)parent).getArgumentList();
|
||||
}
|
||||
else if (parent instanceof PsiAnonymousClass) {
|
||||
return ((PsiAnonymousClass)parent).getArgumentList();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Collection<VirtualFile> getFilesWithPotentialNullPassingCalls(@NotNull PsiMethod method, int parameterIndex) {
|
||||
final FileBasedIndex fileBasedIndex = FileBasedIndex.getInstance();
|
||||
final CommonProcessors.CollectProcessor<VirtualFile> collector = new CommonProcessors.CollectProcessor<>(new ArrayList<>());
|
||||
GlobalSearchScope searchScope = GlobalSearchScopeUtil.toGlobalSearchScope(method.getUseScope(), method.getProject());
|
||||
@@ -84,8 +107,6 @@ public class JavaNullMethodArgumentUtil {
|
||||
Collections.singleton(new JavaNullMethodArgumentIndex.MethodCallData(method.getName(), parameterIndex)),
|
||||
collector,
|
||||
searchScope);
|
||||
final Collection<VirtualFile> candidateFiles = collector.getResults();
|
||||
return candidateFiles.isEmpty() ? null : GlobalSearchScope.filesScope(method.getProject(), candidateFiles);
|
||||
return collector.getResults();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -462,15 +462,14 @@ public class JavaCompletionUtil {
|
||||
}), -1);
|
||||
}
|
||||
if (containsMember(qualifierType, object)) {
|
||||
LookupElementRenderer<LookupElementDecorator<LookupElement>> boldRenderer =
|
||||
new LookupElementRenderer<LookupElementDecorator<LookupElement>>() {
|
||||
@Override
|
||||
public void renderElement(LookupElementDecorator<LookupElement> element, LookupElementPresentation presentation) {
|
||||
element.getDelegate().renderElement(presentation);
|
||||
presentation.setItemTextBold(true);
|
||||
}
|
||||
};
|
||||
return PrioritizedLookupElement.withExplicitProximity(LookupElementDecorator.withRenderer(item, boldRenderer), 1);
|
||||
LookupElementDecorator<LookupElement> bold = LookupElementDecorator.withRenderer(item, new LookupElementRenderer<LookupElementDecorator<LookupElement>>() {
|
||||
@Override
|
||||
public void renderElement(LookupElementDecorator<LookupElement> element, LookupElementPresentation presentation) {
|
||||
element.getDelegate().renderElement(presentation);
|
||||
presentation.setItemTextBold(true);
|
||||
}
|
||||
});
|
||||
return object instanceof PsiField ? bold : PrioritizedLookupElement.withExplicitProximity(bold, 1);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
@@ -885,7 +884,9 @@ public class JavaCompletionUtil {
|
||||
String open = escapeXmlIfNeeded(context, "<");
|
||||
context.getDocument().insertString(offset, open);
|
||||
context.getEditor().getCaretModel().moveToOffset(offset + open.length());
|
||||
context.getDocument().insertString(offset + open.length(), escapeXmlIfNeeded(context, ">"));
|
||||
if (CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET) {
|
||||
context.getDocument().insertString(offset + open.length(), escapeXmlIfNeeded(context, ">"));
|
||||
}
|
||||
if (context.getCompletionChar() != Lookup.COMPLETE_STATEMENT_SELECT_CHAR) {
|
||||
context.setAddCompletionChar(false);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
public class SomeClass {
|
||||
private void b() {
|
||||
List<caret>
|
||||
}
|
||||
}
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import java.util.List;
|
||||
|
||||
public class SomeClass {
|
||||
private void b() {
|
||||
List<<caret>
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -111,7 +111,7 @@ class NormalCompletionOrderingTest extends CompletionSortingTestCase {
|
||||
final String path = getTestName(false) + ".java"
|
||||
myFixture.configureByFile(path)
|
||||
myFixture.complete(CompletionType.BASIC, 2)
|
||||
assertPreferredItems(0, "BOOLEAN", "booleanMethod", "AN_OBJECT", "voidMethod")
|
||||
assertPreferredItems(0, "booleanMethod", "BOOLEAN", "voidMethod", "AN_OBJECT")
|
||||
}
|
||||
|
||||
void testDispreferDeclared() throws Throwable {
|
||||
|
||||
+13
-29
@@ -45,7 +45,7 @@ class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
|
||||
void testSimple() throws Exception {
|
||||
configureByFile("Simple.java")
|
||||
assertStringItems("_field", "_local1", "_local2", "_baseField", "_method", "_baseMethod")
|
||||
assertStringItems("_local1", "_local2", "_field", "_baseField", "_method", "_baseMethod")
|
||||
}
|
||||
|
||||
void testCastToPrimitive1() throws Exception {
|
||||
@@ -222,6 +222,7 @@ class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
protected void tearDown() throws Exception {
|
||||
CodeInsightSettings.instance.AUTOCOMPLETE_ON_CODE_COMPLETION = true
|
||||
CodeInsightSettings.instance.COMPLETION_CASE_SENSITIVE = CodeInsightSettings.FIRST_LETTER
|
||||
CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET = true
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
@@ -361,44 +362,22 @@ class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
}
|
||||
|
||||
void testMethodWithLeftParTailTypeNoPairBrace() throws Exception {
|
||||
final boolean old = CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET
|
||||
CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET = false
|
||||
|
||||
try {
|
||||
configureByFile(getTestName(false) + ".java")
|
||||
type('(')
|
||||
checkResult()
|
||||
}
|
||||
finally {
|
||||
CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET = old
|
||||
}
|
||||
doTest('(')
|
||||
}
|
||||
|
||||
void testMethodWithLeftParTailTypeNoPairBrace2() throws Exception {
|
||||
final boolean old = CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET
|
||||
CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET = false
|
||||
|
||||
try {
|
||||
//no tail type should work the normal way
|
||||
configureByFile("MethodWithLeftParTailTypeNoPairBrace.java")
|
||||
selectItem(myItems[0])
|
||||
checkResultByFile("MethodWithLeftParTailTypeNoPairBrace_after2.java")
|
||||
}
|
||||
finally {
|
||||
CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET = old
|
||||
}
|
||||
//no tail type should work the normal way
|
||||
configureByFile("MethodWithLeftParTailTypeNoPairBrace.java")
|
||||
selectItem(myItems[0])
|
||||
checkResultByFile("MethodWithLeftParTailTypeNoPairBrace_after2.java")
|
||||
}
|
||||
|
||||
void testMethodNoPairBrace() throws Exception {
|
||||
final boolean old = CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET
|
||||
CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET = false
|
||||
|
||||
try {
|
||||
doTest '\n'
|
||||
}
|
||||
finally {
|
||||
CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET = old
|
||||
}
|
||||
doTest '\n'
|
||||
}
|
||||
|
||||
void testExcessSpaceInTypeCast() throws Throwable {
|
||||
@@ -1784,5 +1763,10 @@ class Bar {
|
||||
myFixture.addClass("package pkg; public class PathUtil { public static String toSystemDependentName() {} }")
|
||||
doTest('\n')
|
||||
}
|
||||
|
||||
void testPairAngleBracketDisabled() {
|
||||
CodeInsightSettings.instance.AUTOINSERT_PAIR_BRACKET = false
|
||||
doTest('<')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -473,7 +473,7 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
|
||||
|
||||
public void testNoUninitializedFieldsInConstructor() throws Throwable {
|
||||
configureByTestName();
|
||||
assertStringItems("aab", "aac", "hashCode");
|
||||
assertStringItems("aac", "aab", "hashCode");
|
||||
}
|
||||
public void testFieldsSetInAnotherConstructor() throws Throwable { doTest(); }
|
||||
public void testFieldsSetAbove() throws Throwable { doTest(); }
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ class VariablesCompletionTest extends LightFixtureCompletionTestCase {
|
||||
|
||||
void testLocals2() throws Exception {
|
||||
configureByFile(FILE_PREFIX + "locals/" + "TestSource2.java")
|
||||
myFixture.assertPreferredCompletionItems 0, 'aaa', 'abc'
|
||||
myFixture.assertPreferredCompletionItems 0, 'abc', 'aaa'
|
||||
checkResultByFile(FILE_PREFIX + "locals/" + "TestResult2.java")
|
||||
}
|
||||
|
||||
|
||||
@@ -278,7 +278,7 @@ public class AnalysisScope {
|
||||
final FileIndex fileIndex = getFileIndex();
|
||||
accept(file -> {
|
||||
if (file.isDirectory()) return true;
|
||||
if (ProjectCoreUtil.isProjectOrWorkspaceFile(file, file.getFileType())) return true;
|
||||
if (ProjectCoreUtil.isProjectOrWorkspaceFile(file)) return true;
|
||||
if (fileIndex.isInContent(file) && !isFiltered(file)
|
||||
&& !GeneratedSourcesFilter.isGeneratedSourceByAnyFilter(file, myProject)) {
|
||||
return processFile(file, visitor, psiManager, needReadAction, clearResolveCache);
|
||||
|
||||
@@ -28,12 +28,14 @@ import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.search.scope.packageSet.*;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.SmartHashSet;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public class GlobalSearchScopesCore {
|
||||
@NotNull
|
||||
@@ -58,14 +60,12 @@ public class GlobalSearchScopesCore {
|
||||
|
||||
@NotNull
|
||||
public static GlobalSearchScope directoriesScope(@NotNull Project project, boolean withSubdirectories, @NotNull VirtualFile... directories) {
|
||||
if (directories.length ==1) {
|
||||
if (directories.length == 1) {
|
||||
return directoryScope(project, directories[0], withSubdirectories);
|
||||
}
|
||||
BitSet withSubdirectoriesBS = new BitSet(directories.length);
|
||||
if (withSubdirectories) {
|
||||
withSubdirectoriesBS.set(0, directories.length);
|
||||
}
|
||||
return new DirectoriesScope(project, directories, withSubdirectoriesBS);
|
||||
return new DirectoriesScope(project,
|
||||
withSubdirectories ? Collections.emptySet() : ContainerUtil.newHashSet(directories),
|
||||
withSubdirectories ? ContainerUtil.newHashSet(directories) : Collections.emptySet());
|
||||
}
|
||||
|
||||
public static GlobalSearchScope filterScope(@NotNull Project project, @NotNull NamedScope set) {
|
||||
@@ -220,7 +220,12 @@ public class GlobalSearchScopesCore {
|
||||
|
||||
@Override
|
||||
public boolean contains(@NotNull VirtualFile file) {
|
||||
return myWithSubdirectories ? VfsUtilCore.isAncestor(myDirectory, file, false) : myDirectory.equals(file.getParent());
|
||||
VirtualFile parent = file.getParent();
|
||||
return parent != null && in(parent);
|
||||
}
|
||||
|
||||
private boolean in(@NotNull VirtualFile parent) {
|
||||
return myWithSubdirectories ? VfsUtilCore.isAncestor(myDirectory, parent, false) : myDirectory.equals(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -262,17 +267,22 @@ public class GlobalSearchScopesCore {
|
||||
if (equals(scope)) return this;
|
||||
if (scope instanceof DirectoryScope) {
|
||||
DirectoryScope other = (DirectoryScope)scope;
|
||||
VirtualFile otherDirectory = other.myDirectory;
|
||||
if (myWithSubdirectories && VfsUtilCore.isAncestor(myDirectory, otherDirectory, false)) return this;
|
||||
if (other.myWithSubdirectories && VfsUtilCore.isAncestor(otherDirectory, myDirectory, false)) return other;
|
||||
BitSet newWithSubdirectories = new BitSet();
|
||||
newWithSubdirectories.set(0, myWithSubdirectories);
|
||||
newWithSubdirectories.set(1, other.myWithSubdirectories);
|
||||
return new DirectoriesScope(getProject(), new VirtualFile[]{myDirectory,otherDirectory}, newWithSubdirectories);
|
||||
if (in(other.myDirectory)) return this;
|
||||
if (other.in(myDirectory)) return other;
|
||||
return new DirectoriesScope(getProject(),
|
||||
union(!myWithSubdirectories, myDirectory, !other.myWithSubdirectories, other.myDirectory),
|
||||
union(myWithSubdirectories, myDirectory, other.myWithSubdirectories, other.myDirectory));
|
||||
}
|
||||
return super.uniteWith(scope);
|
||||
}
|
||||
|
||||
private static Set<VirtualFile> union(boolean addDir1, @NotNull VirtualFile dir1, boolean addDir2, @NotNull VirtualFile dir2) {
|
||||
if (addDir1 && addDir2) return ContainerUtil.newHashSet(dir1, dir2);
|
||||
if (addDir1) return Collections.singleton(dir1);
|
||||
if (addDir2) return Collections.singleton(dir2);
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Project getProject() {
|
||||
@@ -288,15 +298,18 @@ public class GlobalSearchScopesCore {
|
||||
}
|
||||
|
||||
static class DirectoriesScope extends GlobalSearchScope {
|
||||
private final VirtualFile[] myDirectories;
|
||||
private final BitSet myWithSubdirectories;
|
||||
private final Set<VirtualFile> myDirectories;
|
||||
private final Set<VirtualFile> myDirectoriesWithSubdirectories;
|
||||
|
||||
private DirectoriesScope(@NotNull Project project, @NotNull VirtualFile[] directories, @NotNull BitSet withSubdirectories) {
|
||||
private DirectoriesScope(@NotNull Project project,
|
||||
@NotNull Set<VirtualFile> directories,
|
||||
@NotNull Set<VirtualFile> directoriesWithSubdirectories) {
|
||||
super(project);
|
||||
myWithSubdirectories = withSubdirectories;
|
||||
myDirectories = directories;
|
||||
if (directories.length < 2) {
|
||||
throw new IllegalArgumentException("Expected >1 directories, but got: " + Arrays.asList(directories));
|
||||
myDirectoriesWithSubdirectories = directoriesWithSubdirectories;
|
||||
if (directories.size() + directoriesWithSubdirectories.size() < 2) {
|
||||
throw new IllegalArgumentException("Expected >1 directories, but got: directories " + directories
|
||||
+ ", directories with subdirectories " + directoriesWithSubdirectories);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,23 +320,10 @@ public class GlobalSearchScopesCore {
|
||||
}
|
||||
|
||||
private boolean in(@NotNull VirtualFile parent) {
|
||||
Set<VirtualFile> directoriesWithSubdirectories = null;
|
||||
for (int i = 0; i < myDirectories.length; i++) {
|
||||
VirtualFile directory = myDirectories[i];
|
||||
boolean withSubdirectories = myWithSubdirectories.get(i);
|
||||
if (withSubdirectories) {
|
||||
if (directory.getFileSystem().equals(parent.getFileSystem())) {
|
||||
if (directoriesWithSubdirectories == null) {
|
||||
directoriesWithSubdirectories = new SmartHashSet<>();
|
||||
}
|
||||
directoriesWithSubdirectories.add(directory);
|
||||
}
|
||||
}
|
||||
else if (directory.equals(parent)) {
|
||||
return true;
|
||||
}
|
||||
if (myDirectories.contains(parent)) {
|
||||
return true;
|
||||
}
|
||||
return VfsUtilCore.isUnder(parent, directoriesWithSubdirectories);
|
||||
return VfsUtilCore.isUnder(parent, myDirectoriesWithSubdirectories);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -344,25 +344,21 @@ public class GlobalSearchScopesCore {
|
||||
@Override
|
||||
public String toString() {
|
||||
//noinspection HardCodedStringLiteral
|
||||
return "Directories scope: " + Arrays.asList(myDirectories);
|
||||
return "Directories scope: directories " + myDirectories + ", directories with subdirectories " + myDirectoriesWithSubdirectories;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
for (int i = 0; i < myDirectories.length; i++) {
|
||||
VirtualFile directory = myDirectories[i];
|
||||
boolean withSubdirectories = myWithSubdirectories.get(i);
|
||||
result = result*31 + directory.hashCode() *31 + (withSubdirectories?1:0);
|
||||
}
|
||||
int result = myDirectories.hashCode();
|
||||
result = result * 31 + myDirectoriesWithSubdirectories.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof DirectoriesScope &&
|
||||
Arrays.equals(myDirectories, ((DirectoriesScope)obj).myDirectories) &&
|
||||
myWithSubdirectories.equals(((DirectoriesScope)obj).myWithSubdirectories);
|
||||
myDirectories.equals(((DirectoriesScope)obj).myDirectories) &&
|
||||
myDirectoriesWithSubdirectories.equals(((DirectoriesScope)obj).myDirectoriesWithSubdirectories);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -372,28 +368,35 @@ public class GlobalSearchScopesCore {
|
||||
return this;
|
||||
}
|
||||
if (scope instanceof DirectoryScope) {
|
||||
if (in(((DirectoryScope)scope).myDirectory)) {
|
||||
DirectoryScope other = (DirectoryScope)scope;
|
||||
if (in(other.myDirectory)) {
|
||||
return this;
|
||||
}
|
||||
VirtualFile[] newDirectories = ArrayUtil.append(myDirectories, ((DirectoryScope)scope).myDirectory, VirtualFile.class);
|
||||
BitSet newWithSubdirectories = (BitSet)myWithSubdirectories.clone();
|
||||
newWithSubdirectories.set(myDirectories.length, ((DirectoryScope)scope).myWithSubdirectories);
|
||||
return new DirectoriesScope(getProject(), newDirectories, newWithSubdirectories);
|
||||
Set<VirtualFile> directories = myDirectories;
|
||||
Set<VirtualFile> directoriesWithSubdirectories = myDirectoriesWithSubdirectories;
|
||||
if (other.myWithSubdirectories) {
|
||||
directoriesWithSubdirectories = new HashSet<>(directoriesWithSubdirectories);
|
||||
directoriesWithSubdirectories.add(other.myDirectory);
|
||||
}
|
||||
else {
|
||||
directories = new HashSet<>(directories);
|
||||
directories.add(other.myDirectory);
|
||||
}
|
||||
return new DirectoriesScope(getProject(), directories, directoriesWithSubdirectories);
|
||||
}
|
||||
if (scope instanceof DirectoriesScope) {
|
||||
DirectoriesScope other = (DirectoriesScope)scope;
|
||||
List<VirtualFile> newDirectories = new ArrayList<>(myDirectories.length + other.myDirectories.length);
|
||||
newDirectories.addAll(Arrays.asList(myDirectories));
|
||||
BitSet newWithSubdirectories = (BitSet)myWithSubdirectories.clone();
|
||||
VirtualFile[] otherDirectories = other.myDirectories;
|
||||
for (int i = 0; i < otherDirectories.length; i++) {
|
||||
VirtualFile otherDirectory = otherDirectories[i];
|
||||
if (!in(otherDirectory)) {
|
||||
newWithSubdirectories.set(newDirectories.size(), other.myWithSubdirectories.get(i));
|
||||
newDirectories.add(otherDirectory);
|
||||
}
|
||||
Set<VirtualFile> directories = myDirectories;
|
||||
Set<VirtualFile> directoriesWithSubdirectories = myDirectoriesWithSubdirectories;
|
||||
if (!other.myDirectories.isEmpty()) {
|
||||
directories = new HashSet<>(directories);
|
||||
directories.addAll(other.myDirectories);
|
||||
}
|
||||
return new DirectoriesScope(getProject(), newDirectories.toArray(new VirtualFile[newDirectories.size()]), newWithSubdirectories);
|
||||
if (!other.myDirectoriesWithSubdirectories.isEmpty()) {
|
||||
directoriesWithSubdirectories = new HashSet<>(directoriesWithSubdirectories);
|
||||
directoriesWithSubdirectories.addAll(other.myDirectoriesWithSubdirectories);
|
||||
}
|
||||
return new DirectoriesScope(getProject(), directories, directoriesWithSubdirectories);
|
||||
}
|
||||
return super.uniteWith(scope);
|
||||
}
|
||||
@@ -408,11 +411,13 @@ public class GlobalSearchScopesCore {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
if (myDirectories.length == 1) {
|
||||
VirtualFile root = myDirectories[0];
|
||||
if (myDirectories.size() + myDirectoriesWithSubdirectories.size() == 1) {
|
||||
Set<VirtualFile> dirs = myDirectories.size() == 1 ? myDirectories : myDirectoriesWithSubdirectories;
|
||||
VirtualFile root = Objects.requireNonNull(ContainerUtil.getFirstItem(dirs));
|
||||
return "Directory '" + root.getName() + "'";
|
||||
}
|
||||
return "Directories " + StringUtil.join(myDirectories, file -> "'" + file.getName() + "'", ", ");
|
||||
Iterable<VirtualFile> allDirs = ContainerUtil.concat(myDirectories, myDirectoriesWithSubdirectories);
|
||||
return "Directories " + StringUtil.join(allDirs, file -> "'" + file.getName() + "'", ", ");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.intellij.openapi.components.impl.stores.IComponentStore
|
||||
import com.intellij.openapi.components.impl.stores.IProjectStore
|
||||
import com.intellij.openapi.components.impl.stores.StoreUtil
|
||||
import com.intellij.openapi.diagnostic.runAndLogException
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.module.ModuleManager
|
||||
import com.intellij.openapi.module.impl.ModuleManagerImpl
|
||||
@@ -243,7 +244,7 @@ abstract class ProjectStoreBase(override final val project: ProjectImpl) : Compo
|
||||
}
|
||||
|
||||
override fun isProjectFile(file: VirtualFile): Boolean {
|
||||
if (!file.isInLocalFileSystem || !ProjectCoreUtil.isProjectOrWorkspaceFile(file, file.fileType)) {
|
||||
if (!file.isInLocalFileSystem || !ProjectCoreUtil.isProjectOrWorkspaceFile(file)) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -141,6 +141,13 @@ public interface Document extends UserDataHolder {
|
||||
@Contract(pure=true)
|
||||
int getLineEndOffset(int line);
|
||||
|
||||
/**
|
||||
* @return whether the line with the given index has been modified since the document has been saved
|
||||
*/
|
||||
default boolean isLineModified(int line) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the specified text at the specified offset in the document. Line breaks in
|
||||
* the inserted text must be normalized as \n.
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.openapi.project;
|
||||
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeRegistry;
|
||||
import com.intellij.openapi.fileTypes.InternalFileType;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.SystemInfoRt;
|
||||
@@ -26,12 +27,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
public class ProjectCoreUtil {
|
||||
public static volatile Project theProject;
|
||||
|
||||
/**
|
||||
* @deprecated Please use ProjectUtil.isProjectOrWorkspaceFile
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isProjectOrWorkspaceFile(@NotNull VirtualFile file) {
|
||||
return isProjectOrWorkspaceFile(file, file.getFileType());
|
||||
// do not use file.getFileType() to avoid autodetection by content loading for arbitrary files
|
||||
return isProjectOrWorkspaceFile(file, FileTypeRegistry.getInstance().getFileTypeByFileName(file.getNameSequence()));
|
||||
}
|
||||
|
||||
public static boolean isProjectOrWorkspaceFile(@NotNull VirtualFile file, @Nullable FileType fileType) {
|
||||
|
||||
@@ -180,6 +180,12 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
|
||||
return stripTrailingSpaces(project, inChangedLinesOnly, true, new int[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLineModified(int line) {
|
||||
LineSet lineSet = myLineSet;
|
||||
return lineSet != null && lineSet.isModified(line);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if stripping was completed successfully, false if the document prevented stripping by e.g. caret(s) being in the way
|
||||
*/
|
||||
|
||||
@@ -518,6 +518,11 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLineModified(int line) {
|
||||
return myDelegate.isLineModified(injectedToHostLine(line));
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Segment[] getHostRanges() {
|
||||
|
||||
@@ -74,7 +74,7 @@ fun guessProjectForFile(file: VirtualFile?): Project? = ProjectLocator.getInstan
|
||||
* guessProjectForFile works incorrectly - even if file is config (idea config file) first opened project will be returned
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun guessProjectForContentFile(file: VirtualFile, fileType: FileType = file.fileType): Project? {
|
||||
fun guessProjectForContentFile(file: VirtualFile, fileType: FileType = FileTypeManager.getInstance().getFileTypeByFileName(file.nameSequence)): Project? {
|
||||
if (ProjectCoreUtil.isProjectOrWorkspaceFile(file, fileType)) {
|
||||
return null
|
||||
}
|
||||
@@ -82,10 +82,7 @@ fun guessProjectForContentFile(file: VirtualFile, fileType: FileType = file.file
|
||||
return ProjectManager.getInstance().openProjects.firstOrNull { !it.isDefault && it.isInitialized && !it.isDisposed && ProjectRootManager.getInstance(it).fileIndex.isInContent(file) }
|
||||
}
|
||||
|
||||
fun isProjectOrWorkspaceFile(file: VirtualFile): Boolean {
|
||||
// do not use file.getFileType() to avoid autodetection by content loading for arbitrary files
|
||||
return ProjectCoreUtil.isProjectOrWorkspaceFile(file, FileTypeManager.getInstance().getFileTypeByFileName(file.name))
|
||||
}
|
||||
fun isProjectOrWorkspaceFile(file: VirtualFile): Boolean = ProjectCoreUtil.isProjectOrWorkspaceFile(file)
|
||||
|
||||
fun guessCurrentProject(component: JComponent?): Project {
|
||||
var project: Project? = null
|
||||
|
||||
+3
-2
@@ -367,12 +367,13 @@ public class GlassPaneDialogWrapperPeer extends DialogWrapperPeer implements Foc
|
||||
private void hidePopupsIfNeeded() {
|
||||
if (!SystemInfo.isMac) return;
|
||||
|
||||
StackingPopupDispatcher.getInstance().hidePersistentPopups();
|
||||
final StackingPopupDispatcher stackingPopupDispatcher = StackingPopupDispatcher.getInstance();
|
||||
stackingPopupDispatcher.hidePersistentPopups();
|
||||
|
||||
Disposer.register(myDialog, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
StackingPopupDispatcher.getInstance().restorePersistentPopups();
|
||||
stackingPopupDispatcher.restorePersistentPopups();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+12
-5
@@ -16,19 +16,24 @@
|
||||
package com.intellij.util;
|
||||
|
||||
import com.intellij.concurrency.JobLauncher;
|
||||
import com.intellij.testFramework.PlatformTestCase;
|
||||
import com.intellij.testFramework.PlatformTestUtil;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
||||
public class StringBuilderSpinAllocatorTest extends PlatformTestCase {
|
||||
public class StringBuilderSpinAllocatorTester {
|
||||
|
||||
public static void main(String[] args) {
|
||||
testSequentialPerformance();
|
||||
testConcurrentPerformance();
|
||||
}
|
||||
|
||||
public static final int THREADS = 1000;
|
||||
|
||||
public void testSequentialPerformance() {
|
||||
private static void testSequentialPerformance() {
|
||||
assumeTrue(!PlatformTestUtil.COVERAGE_ENABLED_BUILD);
|
||||
for (int i=0; i<10; i++) {
|
||||
long spinTime = time(count, spinAlloc);
|
||||
@@ -36,7 +41,7 @@ public class StringBuilderSpinAllocatorTest extends PlatformTestCase {
|
||||
System.out.println("regular: " + regularTime + "; spin :" +spinTime+"; ratio: "+(10*spinTime/regularTime)/10.0+" times");
|
||||
}
|
||||
}
|
||||
public void testConcurrentPerformance() {
|
||||
private static void testConcurrentPerformance() {
|
||||
assumeTrue(!PlatformTestUtil.COVERAGE_ENABLED_BUILD);
|
||||
for (int i=0; i<10; i++) {
|
||||
long spinTime = concurrentTime(count/THREADS, spinAlloc);
|
||||
@@ -53,13 +58,14 @@ public class StringBuilderSpinAllocatorTest extends PlatformTestCase {
|
||||
return true;
|
||||
});
|
||||
|
||||
assertTrue(ok);
|
||||
Assert.assertTrue(ok);
|
||||
});
|
||||
}
|
||||
|
||||
static final int count = 100000;
|
||||
static final int iter = 1000;
|
||||
static Runnable spinAlloc = new Runnable() {
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void run() {
|
||||
for (int i = 0; i < iter; ++i) {
|
||||
@@ -77,6 +83,7 @@ public class StringBuilderSpinAllocatorTest extends PlatformTestCase {
|
||||
}
|
||||
};
|
||||
static Runnable regularAlloc = new Runnable() {
|
||||
@SuppressWarnings("MismatchedQueryAndUpdateOfStringBuilder")
|
||||
@Override
|
||||
public void run() {
|
||||
for (int i = 0; i < iter; ++i) {
|
||||
@@ -18,6 +18,7 @@ package com.intellij.util;
|
||||
|
||||
/**
|
||||
* StringBuilderSpinAllocator reuses StringBuilder instances performing non-blocking allocation and dispose.
|
||||
* @deprecated Simple allocation is faster than this (according to StringBuilderSpinAllocatorTester)
|
||||
*/
|
||||
public class StringBuilderSpinAllocator {
|
||||
|
||||
|
||||
@@ -2008,6 +2008,45 @@ public class UIUtil {
|
||||
drawImage(g, image, x, y, -1, -1, observer);
|
||||
}
|
||||
|
||||
public static void drawImage(Graphics g, Image image, @Nullable Rectangle dstRect, @Nullable Rectangle srcRect, ImageObserver observer) {
|
||||
Image drawImage = image;
|
||||
if (image instanceof JBHiDPIScaledImage) {
|
||||
drawImage = ((JBHiDPIScaledImage)image).getDelegate();
|
||||
if (drawImage == null) {
|
||||
drawImage = image;
|
||||
}
|
||||
}
|
||||
int dx = 0;
|
||||
int dy = 0;
|
||||
int dw = -1;
|
||||
int dh = -1;
|
||||
if (dstRect != null) {
|
||||
dx = dstRect.x;
|
||||
dy = dstRect.y;
|
||||
dw = dstRect.width;
|
||||
dh = dstRect.height;
|
||||
}
|
||||
if (dw == -1 && dh == -1) {
|
||||
dw = ImageUtil.getUserWidth(image);
|
||||
dh = ImageUtil.getUserHeight(image);
|
||||
}
|
||||
int sx = 0;
|
||||
int sy = 0;
|
||||
int sw = -1;
|
||||
int sh = -1;
|
||||
if (srcRect != null) {
|
||||
sx = srcRect.x;
|
||||
sy = srcRect.y;
|
||||
sw = srcRect.width;
|
||||
sh = srcRect.height;
|
||||
}
|
||||
if (sw == -1 && sh == -1) {
|
||||
sw = ImageUtil.getRealWidth(image);
|
||||
sh = ImageUtil.getRealHeight(image);
|
||||
}
|
||||
g.drawImage(drawImage, dx, dy, dx + dw, dy + dh, sx, sy, sx + sw, sy + sh, observer);
|
||||
}
|
||||
|
||||
public static void drawImage(Graphics g, Image image, int x, int y, int width, int height, ImageObserver observer) {
|
||||
if (image instanceof JBHiDPIScaledImage) {
|
||||
Image img = ((JBHiDPIScaledImage)image).getDelegate();
|
||||
@@ -2028,7 +2067,7 @@ public class UIUtil {
|
||||
g.drawImage(image, x, y, observer);
|
||||
}
|
||||
else {
|
||||
g.drawImage(image, x, y, x + width, y + height, observer);
|
||||
g.drawImage(image, x, y, x + width, y + height, 0, 0, width, height, observer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user