Merge remote-tracking branch 'origin/master'
@@ -628,13 +628,12 @@ binding.setVariable("zipSources", { String home, String targetDir ->
|
||||
notifyArtifactBuilt(sources)
|
||||
})
|
||||
|
||||
binding.setVariable("zipSourcesOfModules", { String home, String targetDir, Collection<String> modules ->
|
||||
String sources = "$targetDir/sources.zip"
|
||||
projectBuilder.stage("zip sources of ${modules.size()} modules to $sources")
|
||||
binding.setVariable("zipSourcesOfModules", { String home, String targetFilePath, Collection<String> modules ->
|
||||
projectBuilder.stage("zip sources of ${modules.size()} modules to $targetFilePath")
|
||||
|
||||
ant.mkdir(dir: targetDir)
|
||||
ant.delete(file: sources)
|
||||
ant.zip(destfile: sources) {
|
||||
ant.mkdir(dir: new File(targetFilePath).getParent())
|
||||
ant.delete(file: targetFilePath)
|
||||
ant.zip(destfile: targetFilePath) {
|
||||
modules.each {
|
||||
JpsModule module = findModule(it)
|
||||
module.getSourceRoots(JavaSourceRootType.SOURCE).flatten().collect {it.file}.each { File srcRoot ->
|
||||
@@ -643,7 +642,7 @@ binding.setVariable("zipSourcesOfModules", { String home, String targetDir, Coll
|
||||
}
|
||||
}
|
||||
|
||||
notifyArtifactBuilt(sources)
|
||||
notifyArtifactBuilt(targetFilePath)
|
||||
})
|
||||
|
||||
/**
|
||||
|
||||
@@ -57,7 +57,7 @@ public final class EnterAction extends AnAction {
|
||||
if (selection.length > 0) {
|
||||
if (selection.length == 1 && selection[0].isDirectory()) {
|
||||
presentation.setVisible(true);
|
||||
} else if (selection.length > 0) {
|
||||
} else {
|
||||
boolean notImages = false;
|
||||
ImageFileTypeManager typeManager = ImageFileTypeManager.getInstance();
|
||||
for (VirtualFile file : selection) {
|
||||
@@ -65,9 +65,6 @@ public final class EnterAction extends AnAction {
|
||||
}
|
||||
presentation.setEnabled(!notImages);
|
||||
presentation.setVisible(false);
|
||||
} else {
|
||||
presentation.setVisible(false);
|
||||
presentation.setEnabled(false);
|
||||
}
|
||||
} else {
|
||||
presentation.setVisible(false);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 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.
|
||||
@@ -75,15 +75,23 @@ public class ViewAsGroup extends ActionGroup implements DumbAware {
|
||||
|
||||
final DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(e.getDataContext());
|
||||
final List<JavaValue> values = getSelectedValues(e);
|
||||
final List<XValueNodeImpl> selectedNodes = XDebuggerTreeActionBase.getSelectedNodes(e.getDataContext());
|
||||
|
||||
LOG.assertTrue(debuggerContext != null && !values.isEmpty());
|
||||
|
||||
debuggerContext.getDebugProcess().getManagerThread().schedule(new DebuggerContextCommandImpl(debuggerContext) {
|
||||
DebugProcessImpl process = debuggerContext.getDebugProcess();
|
||||
if (process == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
process.getManagerThread().schedule(new DebuggerContextCommandImpl(debuggerContext) {
|
||||
public void threadAction() {
|
||||
for (JavaValue value : values) {
|
||||
value.getDescriptor().setRenderer(myNodeRenderer);
|
||||
for (final XValueNodeImpl node : selectedNodes) {
|
||||
final XValue container = node.getValueContainer();
|
||||
if (container instanceof JavaValue) {
|
||||
((JavaValue)container).setRenderer(myNodeRenderer, node);
|
||||
}
|
||||
}
|
||||
DebuggerAction.refreshViews(e);
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -106,6 +114,9 @@ public class ViewAsGroup extends ActionGroup implements DumbAware {
|
||||
boolean allApp = true;
|
||||
|
||||
for (JavaValue value : values) {
|
||||
if (value instanceof JavaReferringObjectsValue) { // disable for any referrers at all
|
||||
return AnAction.EMPTY_ARRAY;
|
||||
}
|
||||
ValueDescriptorImpl valueDescriptor = value.getDescriptor();
|
||||
anyValueDescriptor = true;
|
||||
if (!valueDescriptor.isValueValid() || !nodeRenderer.isApplicable(valueDescriptor.getType())) {
|
||||
|
||||
@@ -288,7 +288,7 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
|
||||
return myValueDescriptor.getValueText();
|
||||
}
|
||||
|
||||
private int currentStart = 0;
|
||||
private int myCurrentChildrenStart = 0;
|
||||
|
||||
@Override
|
||||
public void computeChildren(@NotNull final XCompositeNode node) {
|
||||
@@ -326,9 +326,9 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
|
||||
|
||||
@Override
|
||||
public void initChildrenArrayRenderer(ArrayRenderer renderer) {
|
||||
renderer.START_INDEX = currentStart;
|
||||
renderer.END_INDEX = currentStart + XCompositeNode.MAX_CHILDREN_TO_SHOW - 1;
|
||||
currentStart += XCompositeNode.MAX_CHILDREN_TO_SHOW;
|
||||
renderer.START_INDEX = myCurrentChildrenStart;
|
||||
renderer.END_INDEX = myCurrentChildrenStart + XCompositeNode.MAX_CHILDREN_TO_SHOW - 1;
|
||||
myCurrentChildrenStart += XCompositeNode.MAX_CHILDREN_TO_SHOW;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -456,14 +456,14 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
|
||||
public String getEvaluationExpression() {
|
||||
if (evaluationExpression == null) {
|
||||
// TODO: change API to allow to calculate it asynchronously
|
||||
myEvaluationContext.getManagerThread().invokeAndWait(new DebuggerCommandImpl() {
|
||||
myEvaluationContext.getManagerThread().invokeAndWait(new SuspendContextCommandImpl(myEvaluationContext.getSuspendContext()) {
|
||||
@Override
|
||||
public Priority getPriority() {
|
||||
return Priority.HIGH;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void action() throws Exception {
|
||||
public void contextAction() throws Exception {
|
||||
evaluationExpression = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
@Override
|
||||
public String compute() {
|
||||
@@ -536,4 +536,17 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void setRenderer(NodeRenderer nodeRenderer, final XValueNodeImpl node) {
|
||||
DebuggerManagerThreadImpl.assertIsManagerThread();
|
||||
myValueDescriptor.setRenderer(nodeRenderer);
|
||||
myCurrentChildrenStart = 0;
|
||||
node.getTree().getLaterInvocator().offer(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
node.clearChildren();
|
||||
computePresentation(node, XValuePlace.TREE);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.Predicate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -99,6 +100,37 @@ public abstract class PsiElementFinder {
|
||||
return PsiClass.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of children (classes, subpackages and possibly other elements) belonging to the specified package.
|
||||
*
|
||||
* @param psiPackage the package to return the list of children for.
|
||||
* @param scope the scope in which children are searched.
|
||||
* @return the list of children.
|
||||
* @since 14.1
|
||||
*/
|
||||
@NotNull
|
||||
public PsiNamedElement[] getChildren(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
|
||||
Set<PsiNamedElement> children = new HashSet<PsiNamedElement>();
|
||||
Collections.addAll(children, getSubPackages(psiPackage, scope));
|
||||
Collections.addAll(children, getClasses(psiPackage, scope));
|
||||
return children.toArray(new PsiNamedElement[children.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filter to use for filtering the list of children for a given package produced by other PsiElementFinder
|
||||
* implementations. (For example, the list of children for a Kotlin package includes files directly, rather than classes,
|
||||
* so the classes located by the standard Java package children finder need to be excluded.)
|
||||
*
|
||||
* @param psiPackage the package to return the list of children for.
|
||||
* @param scope the scope in which children are searched.
|
||||
* @return the filter to use, or null if no additional filtering is necessary.
|
||||
* @since 14.1
|
||||
*/
|
||||
@Nullable
|
||||
public Predicate<PsiNamedElement> getPackageChildrenFilter(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A method to optimize resolve (to only search classes in a package which might be there)
|
||||
*/
|
||||
|
||||
@@ -83,6 +83,14 @@ public interface PsiPackage extends PsiCheckedRenameElement, NavigationItem, Psi
|
||||
@NotNull
|
||||
PsiClass[] getClasses(@NotNull GlobalSearchScope scope);
|
||||
|
||||
/**
|
||||
* Returns the list of all elements (classes, subpackages and potentially other elements) belonging to this package
|
||||
* (non-recursively), restricted by the specified scope.
|
||||
*
|
||||
* @since 14.1
|
||||
*/
|
||||
PsiElement[] getChildren(@NotNull GlobalSearchScope scope);
|
||||
|
||||
/**
|
||||
* Returns the list of package-level annotations for the package.
|
||||
*
|
||||
|
||||
@@ -57,6 +57,8 @@ public abstract class PsiAugmentProvider {
|
||||
* @param typeElement place where inference takes place,
|
||||
* also nested PsiTypeElement-s (e.g. for List<String> PsiTypeElements corresponding to both List and String would be suggested)
|
||||
* @return inferred type or null, if inference is not applicable
|
||||
*
|
||||
* @since 14.1
|
||||
*/
|
||||
@Nullable
|
||||
protected PsiType inferType(PsiTypeElement typeElement) {
|
||||
|
||||
@@ -16,16 +16,11 @@
|
||||
package com.intellij.psi.impl;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ReadActionProcessor;
|
||||
import com.intellij.openapi.progress.ProgressIndicatorProvider;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.FileIndexFacade;
|
||||
import com.intellij.openapi.roots.PackageIndex;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileFilter;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.file.impl.JavaFileManager;
|
||||
@@ -34,15 +29,14 @@ import com.intellij.psi.impl.source.JavaDummyHolder;
|
||||
import com.intellij.psi.impl.source.JavaDummyHolderFactory;
|
||||
import com.intellij.psi.impl.source.resolve.FileContextUtil;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.stubs.StubTreeLoader;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.reference.SoftReference;
|
||||
import com.intellij.util.ConcurrencyUtil;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.Predicate;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -94,7 +88,7 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
|
||||
public PsiClass findClass(@NotNull final String qualifiedName, @NotNull GlobalSearchScope scope) {
|
||||
ProgressIndicatorProvider.checkCanceled(); // We hope this method is being called often enough to cancel daemon processes smoothly
|
||||
|
||||
if (DumbService.getInstance(getProject()).isDumb()) {
|
||||
if (shouldUseSlowResolve()) {
|
||||
PsiClass[] classes = findClassesInDumbMode(qualifiedName, scope);
|
||||
if (classes.length != 0) {
|
||||
return classes[0];
|
||||
@@ -134,7 +128,7 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClass[] findClasses(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
|
||||
if (DumbService.getInstance(getProject()).isDumb()) {
|
||||
if (shouldUseSlowResolve()) {
|
||||
return findClassesInDumbMode(qualifiedName, scope);
|
||||
}
|
||||
|
||||
@@ -147,6 +141,11 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
|
||||
return classes.toArray(new PsiClass[classes.size()]);
|
||||
}
|
||||
|
||||
private boolean shouldUseSlowResolve() {
|
||||
DumbService dumbService = DumbService.getInstance(getProject());
|
||||
return dumbService.isDumb() && dumbService.isAlternativeResolveEnabled();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PsiElementFinder[] finders() {
|
||||
PsiElementFinder[] answer = myElementFinders;
|
||||
@@ -161,7 +160,6 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
|
||||
@NotNull
|
||||
private PsiElementFinder[] calcFinders() {
|
||||
List<PsiElementFinder> elementFinders = new ArrayList<PsiElementFinder>();
|
||||
elementFinders.add(new PsiElementFinderImpl());
|
||||
ContainerUtil.addAll(elementFinders, myProject.getExtensions(PsiElementFinder.EP_NAME));
|
||||
return elementFinders.toArray(new PsiElementFinder[elementFinders.size()]);
|
||||
}
|
||||
@@ -245,6 +243,56 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
|
||||
return result == null ? PsiClass.EMPTY_ARRAY : result.toArray(new PsiClass[result.size()]);
|
||||
}
|
||||
|
||||
private static class AndPredicate implements Predicate<PsiNamedElement> {
|
||||
private final List<Predicate<PsiNamedElement>> myComponents = new SmartList<Predicate<PsiNamedElement>>();
|
||||
|
||||
public AndPredicate(Predicate<PsiNamedElement> filter1, Predicate<PsiNamedElement> filter2) {
|
||||
myComponents.add(filter1);
|
||||
myComponents.add(filter2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(@Nullable PsiNamedElement input) {
|
||||
for (Predicate<PsiNamedElement> component : myComponents) {
|
||||
if (!component.apply(input)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiElement[] getPackageChildren(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
|
||||
Map<String, PsiNamedElement> result = new HashMap<String, PsiNamedElement>();
|
||||
Predicate<PsiNamedElement> filter = null;
|
||||
|
||||
for (PsiElementFinder finder : filteredFinders()) {
|
||||
Predicate<PsiNamedElement> finderFilter = finder.getPackageChildrenFilter(psiPackage, scope);
|
||||
if (finderFilter != null) {
|
||||
if (filter == null) {
|
||||
filter = finderFilter;
|
||||
}
|
||||
else if (filter instanceof AndPredicate) {
|
||||
((AndPredicate) filter).myComponents.add(finderFilter);
|
||||
}
|
||||
else {
|
||||
filter = new AndPredicate(filter, finderFilter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (PsiElementFinder finder : filteredFinders()) {
|
||||
PsiNamedElement[] children = finder.getChildren(psiPackage, scope);
|
||||
for (PsiNamedElement child : children) {
|
||||
if (!result.containsKey(child.getName()) && (filter == null || filter.apply(child))) {
|
||||
result.put(child.getName(), child);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.values().toArray(new PsiElement[result.size()]);
|
||||
}
|
||||
|
||||
public boolean processPackageDirectories(@NotNull PsiPackage psiPackage,
|
||||
@NotNull GlobalSearchScope scope,
|
||||
@NotNull Processor<PsiDirectory> consumer,
|
||||
@@ -274,146 +322,6 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
|
||||
return result.values().toArray(new PsiPackage[result.size()]);
|
||||
}
|
||||
|
||||
public PsiClass[] findClassByShortName(String name, PsiPackage psiPackage, GlobalSearchScope scope) {
|
||||
List<PsiClass> result = null;
|
||||
for (PsiElementFinder finder : filteredFinders()) {
|
||||
PsiClass[] classes = finder.getClasses(name, psiPackage, scope);
|
||||
if (classes.length == 0) continue;
|
||||
if (result == null) result = new ArrayList<PsiClass>();
|
||||
ContainerUtil.addAll(result, classes);
|
||||
}
|
||||
|
||||
return result == null ? PsiClass.EMPTY_ARRAY : result.toArray(new PsiClass[result.size()]);
|
||||
}
|
||||
|
||||
private class PsiElementFinderImpl extends PsiElementFinder implements DumbAware {
|
||||
@Override
|
||||
public PsiClass findClass(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
|
||||
return myFileManager.findClass(qualifiedName, scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClass[] findClasses(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
|
||||
return myFileManager.findClasses(qualifiedName, scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiPackage findPackage(@NotNull String qualifiedName) {
|
||||
return myFileManager.findPackage(qualifiedName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiPackage[] getSubPackages(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
|
||||
final Map<String, PsiPackage> packagesMap = new HashMap<String, PsiPackage>();
|
||||
final String qualifiedName = psiPackage.getQualifiedName();
|
||||
for (PsiDirectory dir : psiPackage.getDirectories(scope)) {
|
||||
PsiDirectory[] subDirs = dir.getSubdirectories();
|
||||
for (PsiDirectory subDir : subDirs) {
|
||||
final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(subDir);
|
||||
if (aPackage != null) {
|
||||
final String subQualifiedName = aPackage.getQualifiedName();
|
||||
if (subQualifiedName.startsWith(qualifiedName) && !packagesMap.containsKey(subQualifiedName)) {
|
||||
packagesMap.put(aPackage.getQualifiedName(), aPackage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
packagesMap.remove(qualifiedName); // avoid SOE caused by returning a package as a subpackage of itself
|
||||
return packagesMap.values().toArray(new PsiPackage[packagesMap.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClass[] getClasses(@NotNull PsiPackage psiPackage, @NotNull final GlobalSearchScope scope) {
|
||||
return getClasses(null, psiPackage, scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClass[] getClasses(@Nullable String shortName, @NotNull PsiPackage psiPackage, @NotNull final GlobalSearchScope scope) {
|
||||
List<PsiClass> list = null;
|
||||
String packageName = psiPackage.getQualifiedName();
|
||||
for (PsiDirectory dir : psiPackage.getDirectories(scope)) {
|
||||
PsiClass[] classes = JavaDirectoryService.getInstance().getClasses(dir);
|
||||
if (classes.length == 0) continue;
|
||||
if (list == null) list = new ArrayList<PsiClass>();
|
||||
for (PsiClass aClass : classes) {
|
||||
// class file can be located in wrong place inside file system
|
||||
String qualifiedName = aClass.getQualifiedName();
|
||||
if (qualifiedName != null) qualifiedName = StringUtil.getPackageName(qualifiedName);
|
||||
if (Comparing.strEqual(qualifiedName, packageName)) {
|
||||
if (shortName == null || shortName.equals(aClass.getName())) list.add(aClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (list == null) {
|
||||
return PsiClass.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
if (list.size() > 1) {
|
||||
ContainerUtil.quickSort(list, new Comparator<PsiClass>() {
|
||||
@Override
|
||||
public int compare(PsiClass o1, PsiClass o2) {
|
||||
VirtualFile file1 = PsiUtilCore.getVirtualFile(o1);
|
||||
VirtualFile file2 = PsiUtilCore.getVirtualFile(o2);
|
||||
return file1 == null ? file2 == null ? 0 : -1 : file2 == null ? 1 : scope.compare(file2, file1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return list.toArray(new PsiClass[list.size()]);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<String> getClassNames(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
|
||||
Set<String> names = null;
|
||||
FileIndexFacade facade = FileIndexFacade.getInstance(myProject);
|
||||
for (PsiDirectory dir : psiPackage.getDirectories(scope)) {
|
||||
for (PsiFile file : dir.getFiles()) {
|
||||
if (file instanceof PsiClassOwner && file.getViewProvider().getLanguages().size() == 1) {
|
||||
VirtualFile vFile = file.getVirtualFile();
|
||||
if (vFile != null &&
|
||||
!(file instanceof PsiCompiledElement) &&
|
||||
!facade.isInSourceContent(vFile) &&
|
||||
(!scope.isForceSearchingInLibrarySources() ||
|
||||
!StubTreeLoader.getInstance().canHaveStub(vFile))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<String> inFile = file instanceof PsiClassOwnerEx ? ((PsiClassOwnerEx)file).getClassNames() : getClassNames(((PsiClassOwner)file).getClasses());
|
||||
|
||||
if (inFile.isEmpty()) continue;
|
||||
if (names == null) names = new HashSet<String>();
|
||||
names.addAll(inFile);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return names == null ? Collections.<String>emptySet() : names;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processPackageDirectories(@NotNull PsiPackage psiPackage,
|
||||
@NotNull final GlobalSearchScope scope,
|
||||
@NotNull final Processor<PsiDirectory> consumer,
|
||||
boolean includeLibrarySources) {
|
||||
final PsiManager psiManager = PsiManager.getInstance(getProject());
|
||||
return PackageIndex.getInstance(getProject()).getDirsByPackageName(psiPackage.getQualifiedName(), includeLibrarySources)
|
||||
.forEach(new ReadActionProcessor<VirtualFile>() {
|
||||
@Override
|
||||
public boolean processInReadAction(final VirtualFile dir) {
|
||||
if (!scope.contains(dir)) return true;
|
||||
PsiDirectory psiDir = psiManager.findDirectory(dir);
|
||||
return psiDir == null || consumer.process(psiDir);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPartOfPackagePrefix(@NotNull String packageName) {
|
||||
final Collection<String> packagePrefixes = myFileManager.getNonTrivialPackagePrefixes();
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.psi.impl;
|
||||
|
||||
import com.intellij.openapi.application.ReadActionProcessor;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.FileIndexFacade;
|
||||
import com.intellij.openapi.roots.PackageIndex;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.file.impl.JavaFileManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.stubs.StubTreeLoader;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by kosyakov on 05.12.14.
|
||||
*/
|
||||
public class PsiElementFinderImpl extends PsiElementFinder implements DumbAware {
|
||||
|
||||
private final Project myProject;
|
||||
private final JavaFileManager myFileManager;
|
||||
|
||||
public PsiElementFinderImpl(Project project, JavaFileManager javaFileManager) {
|
||||
this.myProject = project;
|
||||
this.myFileManager = javaFileManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiClass findClass(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
|
||||
return myFileManager.findClass(qualifiedName, scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClass[] findClasses(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
|
||||
return myFileManager.findClasses(qualifiedName, scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiPackage findPackage(@NotNull String qualifiedName) {
|
||||
return myFileManager.findPackage(qualifiedName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiPackage[] getSubPackages(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
|
||||
final Map<String, PsiPackage> packagesMap = new HashMap<String, PsiPackage>();
|
||||
final String qualifiedName = psiPackage.getQualifiedName();
|
||||
for (PsiDirectory dir : psiPackage.getDirectories(scope)) {
|
||||
PsiDirectory[] subDirs = dir.getSubdirectories();
|
||||
for (PsiDirectory subDir : subDirs) {
|
||||
final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(subDir);
|
||||
if (aPackage != null) {
|
||||
final String subQualifiedName = aPackage.getQualifiedName();
|
||||
if (subQualifiedName.startsWith(qualifiedName) && !packagesMap.containsKey(subQualifiedName)) {
|
||||
packagesMap.put(aPackage.getQualifiedName(), aPackage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
packagesMap.remove(qualifiedName); // avoid SOE caused by returning a package as a subpackage of itself
|
||||
return packagesMap.values().toArray(new PsiPackage[packagesMap.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClass[] getClasses(@NotNull PsiPackage psiPackage, @NotNull final GlobalSearchScope scope) {
|
||||
return getClasses(null, psiPackage, scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClass[] getClasses(@Nullable String shortName, @NotNull PsiPackage psiPackage, @NotNull final GlobalSearchScope scope) {
|
||||
List<PsiClass> list = null;
|
||||
String packageName = psiPackage.getQualifiedName();
|
||||
for (PsiDirectory dir : psiPackage.getDirectories(scope)) {
|
||||
PsiClass[] classes = JavaDirectoryService.getInstance().getClasses(dir);
|
||||
if (classes.length == 0) continue;
|
||||
if (list == null) list = new ArrayList<PsiClass>();
|
||||
for (PsiClass aClass : classes) {
|
||||
// class file can be located in wrong place inside file system
|
||||
String qualifiedName = aClass.getQualifiedName();
|
||||
if (qualifiedName != null) qualifiedName = StringUtil.getPackageName(qualifiedName);
|
||||
if (Comparing.strEqual(qualifiedName, packageName)) {
|
||||
if (shortName == null || shortName.equals(aClass.getName())) list.add(aClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (list == null) {
|
||||
return PsiClass.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
if (list.size() > 1) {
|
||||
ContainerUtil.quickSort(list, new Comparator<PsiClass>() {
|
||||
@Override
|
||||
public int compare(PsiClass o1, PsiClass o2) {
|
||||
VirtualFile file1 = PsiUtilCore.getVirtualFile(o1);
|
||||
VirtualFile file2 = PsiUtilCore.getVirtualFile(o2);
|
||||
return file1 == null ? file2 == null ? 0 : -1 : file2 == null ? 1 : scope.compare(file2, file1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return list.toArray(new PsiClass[list.size()]);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<String> getClassNames(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
|
||||
Set<String> names = null;
|
||||
FileIndexFacade facade = FileIndexFacade.getInstance(myProject);
|
||||
for (PsiDirectory dir : psiPackage.getDirectories(scope)) {
|
||||
for (PsiFile file : dir.getFiles()) {
|
||||
if (file instanceof PsiClassOwner && file.getViewProvider().getLanguages().size() == 1) {
|
||||
VirtualFile vFile = file.getVirtualFile();
|
||||
if (vFile != null &&
|
||||
!(file instanceof PsiCompiledElement) &&
|
||||
!facade.isInSourceContent(vFile) &&
|
||||
(!scope.isForceSearchingInLibrarySources() || !StubTreeLoader.getInstance().canHaveStub(vFile))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<String> inFile =
|
||||
file instanceof PsiClassOwnerEx ? ((PsiClassOwnerEx)file).getClassNames() : getClassNames(((PsiClassOwner)file).getClasses());
|
||||
|
||||
if (inFile.isEmpty()) continue;
|
||||
if (names == null) names = new HashSet<String>();
|
||||
names.addAll(inFile);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return names == null ? Collections.<String>emptySet() : names;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processPackageDirectories(@NotNull PsiPackage psiPackage,
|
||||
@NotNull final GlobalSearchScope scope,
|
||||
@NotNull final Processor<PsiDirectory> consumer,
|
||||
boolean includeLibrarySources) {
|
||||
final PsiManager psiManager = PsiManager.getInstance(myProject);
|
||||
return PackageIndex.getInstance(myProject).getDirsByPackageName(psiPackage.getQualifiedName(), includeLibrarySources)
|
||||
.forEach(new ReadActionProcessor<VirtualFile>() {
|
||||
@Override
|
||||
public boolean processInReadAction(final VirtualFile dir) {
|
||||
if (!scope.contains(dir)) return true;
|
||||
PsiDirectory psiDir = psiManager.findDirectory(dir);
|
||||
return psiDir == null || consumer.process(psiDir);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -153,6 +153,17 @@ public class PsiPackageImpl extends PsiPackageBase implements PsiPackage, Querya
|
||||
return getFacade().getClasses(this, scope);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElement[] getChildren() {
|
||||
return getChildren(allScope());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement[] getChildren(@NotNull GlobalSearchScope scope) {
|
||||
return getFacade().getPackageChildren(this, scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PsiModifierList getAnnotationList() {
|
||||
|
||||
@@ -193,8 +193,7 @@ public class JavacMain {
|
||||
|
||||
private static boolean canUseOptimizedFileManager(JavaCompilingTool compilingTool) {
|
||||
// since java 9 internal API's used by the optimizedFileManager have changed
|
||||
return compilingTool instanceof JavacCompilerTool &&
|
||||
(JAVA_VERSION.contains("1.6") || JAVA_VERSION.contains("1.7") || JAVA_VERSION.contains("1.8"));
|
||||
return compilingTool instanceof JavacCompilerTool && !SystemInfo.isJavaVersionAtLeast("1.9");
|
||||
}
|
||||
|
||||
private static void handleCancelException(DiagnosticOutputConsumer diagnosticConsumer) {
|
||||
|
||||
@@ -34,7 +34,7 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* A service managing IDEA's 'dumb' mode: when indices are updated in background and the functionality is very much limited.
|
||||
* Only the explicitly allowed functionality is available. Usually it's allowed by implementing {@link com.intellij.openapi.project.DumbAware} interface.
|
||||
* Only the explicitly allowed functionality is available. Usually it's allowed by implementing {@link DumbAware} interface.
|
||||
*
|
||||
* If you want to register a toolwindow, which will be enabled during the dumb mode, please use {@link com.intellij.openapi.wm.ToolWindowManager}'s
|
||||
* registration methods which have 'canWorkInDumMode' parameter.
|
||||
@@ -45,7 +45,7 @@ public abstract class DumbService {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.project.DumbService");
|
||||
|
||||
/**
|
||||
* @see com.intellij.openapi.project.Project#getMessageBus()
|
||||
* @see Project#getMessageBus()
|
||||
*/
|
||||
public static final Topic<DumbModeListener> DUMB_MODE = new Topic<DumbModeListener>("dumb mode", DumbModeListener.class);
|
||||
|
||||
@@ -210,6 +210,26 @@ public abstract class DumbService {
|
||||
return o instanceof DumbAware;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables alternative resolve strategies for the current thread.<p/>
|
||||
*
|
||||
* Normally reference resolution uses index, and hence is not available in dumb mode. In some cases, alternative ways
|
||||
* of performing resolve are available, although much slower. It's impractical to always use these ways because it'll
|
||||
* lead to overloaded CPU (especially given there's also indexing in progress). But for some explicit user actions
|
||||
* (e.g. explicit Goto Declaration) turning these slower methods is beneficial.<p/>
|
||||
*
|
||||
* A typical usage would involve try-finally, where the alternative resolution is first enabled, then an action is performed,
|
||||
* and then alternative resolution is turned off in the finally block.
|
||||
*/
|
||||
public abstract void setAlternativeResolveEnabled(boolean enabled);
|
||||
|
||||
/**
|
||||
* @return whether alternative resolution is enabled for the current thread.
|
||||
*
|
||||
* @see #setAlternativeResolveEnabled(boolean)
|
||||
*/
|
||||
public abstract boolean isAlternativeResolveEnabled();
|
||||
|
||||
/**
|
||||
* @see #DUMB_MODE
|
||||
*/
|
||||
|
||||
@@ -74,6 +74,15 @@ public class MockDumbService extends DumbService {
|
||||
return myProject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlternativeResolveEnabled(boolean enabled) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAlternativeResolveEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void smartInvokeLater(@NotNull final Runnable runnable) {
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 528 B After Width: | Height: | Size: 130 B |
|
After Width: | Height: | Size: 253 B |
|
After Width: | Height: | Size: 245 B |
|
After Width: | Height: | Size: 133 B |
|
Before Width: | Height: | Size: 687 B After Width: | Height: | Size: 384 B |
|
After Width: | Height: | Size: 516 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1022 B |
|
After Width: | Height: | Size: 843 B |
|
Before Width: | Height: | Size: 754 B After Width: | Height: | Size: 474 B |
|
After Width: | Height: | Size: 598 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 593 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 506 B |
|
Before Width: | Height: | Size: 482 B After Width: | Height: | Size: 252 B |
|
After Width: | Height: | Size: 419 B |
|
After Width: | Height: | Size: 406 B |
|
After Width: | Height: | Size: 255 B |
|
Before Width: | Height: | Size: 503 B After Width: | Height: | Size: 503 B |
|
Before Width: | Height: | Size: 735 B After Width: | Height: | Size: 531 B |
|
After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 552 B After Width: | Height: | Size: 552 B |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 641 B After Width: | Height: | Size: 378 B |
|
After Width: | Height: | Size: 655 B |
|
Before Width: | Height: | Size: 797 B After Width: | Height: | Size: 558 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 682 B After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 523 B |
|
Before Width: | Height: | Size: 162 B After Width: | Height: | Size: 116 B |
|
After Width: | Height: | Size: 138 B |
|
After Width: | Height: | Size: 141 B |
|
After Width: | Height: | Size: 120 B |
|
Before Width: | Height: | Size: 686 B After Width: | Height: | Size: 266 B |
|
After Width: | Height: | Size: 393 B |
|
After Width: | Height: | Size: 394 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 343 B |
|
After Width: | Height: | Size: 528 B |
|
After Width: | Height: | Size: 529 B |
|
After Width: | Height: | Size: 336 B |
|
After Width: | Height: | Size: 263 B |
|
Before Width: | Height: | Size: 759 B After Width: | Height: | Size: 513 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 141 B After Width: | Height: | Size: 234 B |
|
After Width: | Height: | Size: 453 B |
|
After Width: | Height: | Size: 456 B |
|
After Width: | Height: | Size: 232 B |
|
Before Width: | Height: | Size: 788 B After Width: | Height: | Size: 554 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 797 B After Width: | Height: | Size: 537 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 711 B After Width: | Height: | Size: 305 B |
|
After Width: | Height: | Size: 881 B |
|
Before Width: | Height: | Size: 772 B After Width: | Height: | Size: 461 B |
|
After Width: | Height: | Size: 837 B |
|
After Width: | Height: | Size: 839 B |
|
Before Width: | Height: | Size: 765 B After Width: | Height: | Size: 504 B |
|
After Width: | Height: | Size: 911 B |
|
After Width: | Height: | Size: 884 B |
|
After Width: | Height: | Size: 502 B |
|
After Width: | Height: | Size: 459 B |
|
Before Width: | Height: | Size: 656 B After Width: | Height: | Size: 295 B |
|
After Width: | Height: | Size: 517 B |
|
Before Width: | Height: | Size: 742 B After Width: | Height: | Size: 425 B |
|
After Width: | Height: | Size: 955 B |
|
Before Width: | Height: | Size: 686 B After Width: | Height: | Size: 281 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 280 B |
|
Before Width: | Height: | Size: 729 B After Width: | Height: | Size: 286 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 788 B After Width: | Height: | Size: 554 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 287 B |
|
Before Width: | Height: | Size: 747 B After Width: | Height: | Size: 447 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 590 B After Width: | Height: | Size: 399 B |
|
After Width: | Height: | Size: 834 B |
|
After Width: | Height: | Size: 860 B |
|
After Width: | Height: | Size: 400 B |
|
After Width: | Height: | Size: 447 B |
|
Before Width: | Height: | Size: 704 B After Width: | Height: | Size: 398 B |