mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'goto-module'
This commit is contained in:
@@ -89,6 +89,7 @@
|
||||
<stubIndex implementation="com.jetbrains.python.psi.stubs.PySuperClassIndex"/>
|
||||
<stubIndex implementation="com.jetbrains.python.psi.stubs.PyVariableNameIndex"/>
|
||||
<stubIndex implementation="com.jetbrains.python.psi.stubs.PyInstanceAttributeIndex"/>
|
||||
<fileBasedIndex implementation="com.jetbrains.python.psi.stubs.PyModuleNameIndex"/>
|
||||
|
||||
<declarationRangeHandler key="com.jetbrains.python.psi.PyClass"
|
||||
implementationClass="com.jetbrains.python.codeInsight.PyDeclarationRangeHandler"/>
|
||||
|
||||
@@ -19,11 +19,14 @@ import com.intellij.navigation.ChooseByNameContributor;
|
||||
import com.intellij.navigation.NavigationItem;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.jetbrains.python.psi.PyClass;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.jetbrains.python.psi.stubs.PyClassNameIndex;
|
||||
import com.jetbrains.python.psi.stubs.PyModuleNameIndex;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
@@ -31,13 +34,18 @@ import java.util.Collection;
|
||||
public class PyGotoClassContributor implements ChooseByNameContributor {
|
||||
@NotNull
|
||||
public String[] getNames(final Project project, final boolean includeNonProjectItems) {
|
||||
final Collection<String> classNames = PyClassNameIndex.allKeys(project);
|
||||
return ArrayUtil.toStringArray(classNames);
|
||||
Set<String> results = new HashSet<String>();
|
||||
results.addAll(PyClassNameIndex.allKeys(project));
|
||||
results.addAll(PyModuleNameIndex.getAllKeys(project));
|
||||
return ArrayUtil.toStringArray(results);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public NavigationItem[] getItemsByName(final String name, final String pattern, final Project project, final boolean includeNonProjectItems) {
|
||||
final Collection<PyClass> classes = PyClassNameIndex.find(name, project, includeNonProjectItems);
|
||||
return classes.toArray(new NavigationItem[classes.size()]);
|
||||
public NavigationItem[] getItemsByName(final String name, final String pattern, final Project project,
|
||||
final boolean includeNonProjectItems) {
|
||||
final List<NavigationItem> results = new ArrayList<NavigationItem>();
|
||||
results.addAll(PyClassNameIndex.find(name, project, includeNonProjectItems));
|
||||
results.addAll(PyModuleNameIndex.find(name, project, includeNonProjectItems));
|
||||
return results.toArray(new NavigationItem[results.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.jetbrains.python.psi.PyQualifiedNameOwner;
|
||||
import com.jetbrains.python.psi.search.PyProjectScopeBuilder;
|
||||
import com.jetbrains.python.psi.stubs.PyClassNameIndex;
|
||||
import com.jetbrains.python.psi.stubs.PyFunctionNameIndex;
|
||||
import com.jetbrains.python.psi.stubs.PyModuleNameIndex;
|
||||
import com.jetbrains.python.psi.stubs.PyVariableNameIndex;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -41,6 +42,7 @@ public class PyGotoSymbolContributor implements GotoClassContributor {
|
||||
public String[] getNames(final Project project, final boolean includeNonProjectItems) {
|
||||
Set<String> symbols = new HashSet<String>();
|
||||
symbols.addAll(PyClassNameIndex.allKeys(project));
|
||||
symbols.addAll(PyModuleNameIndex.getAllKeys(project));
|
||||
symbols.addAll(StubIndex.getInstance().getAllKeys(PyFunctionNameIndex.KEY, project));
|
||||
symbols.addAll(StubIndex.getInstance().getAllKeys(PyVariableNameIndex.KEY, project));
|
||||
return ArrayUtil.toStringArray(symbols);
|
||||
@@ -54,6 +56,7 @@ public class PyGotoSymbolContributor implements GotoClassContributor {
|
||||
|
||||
List<NavigationItem> symbols = new ArrayList<NavigationItem>();
|
||||
symbols.addAll(PyClassNameIndex.find(name, project, scope));
|
||||
symbols.addAll(PyModuleNameIndex.find(name, project, includeNonProjectItems));
|
||||
symbols.addAll(PyFunctionNameIndex.find(name, project, scope));
|
||||
symbols.addAll(PyVariableNameIndex.find(name, project, scope));
|
||||
|
||||
|
||||
@@ -16,15 +16,19 @@
|
||||
package com.jetbrains.python.psi.impl;
|
||||
|
||||
import com.intellij.extapi.psi.PsiFileBase;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.navigation.ItemPresentation;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
import com.intellij.psi.util.QualifiedName;
|
||||
@@ -33,11 +37,15 @@ import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.indexing.IndexingDataKeys;
|
||||
import com.jetbrains.python.*;
|
||||
import com.jetbrains.python.PyElementTypes;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.PythonFileType;
|
||||
import com.jetbrains.python.PythonLanguage;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache;
|
||||
import com.jetbrains.python.documentation.DocStringUtil;
|
||||
import com.jetbrains.python.inspections.PythonVisitorFilter;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.resolve.QualifiedNameFinder;
|
||||
import com.jetbrains.python.psi.resolve.RatedResolveResult;
|
||||
import com.jetbrains.python.psi.resolve.ResolveImportUtil;
|
||||
import com.jetbrains.python.psi.resolve.VariantsProcessor;
|
||||
@@ -49,6 +57,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
|
||||
@@ -770,4 +779,78 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
|
||||
}
|
||||
return elementType == PyElementTypes.IMPORT_STATEMENT || elementType == PyElementTypes.FROM_IMPORT_STATEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemPresentation getPresentation() {
|
||||
return new ItemPresentation() {
|
||||
@Override
|
||||
public String getPresentableText() {
|
||||
return getModuleName(PyFileImpl.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocationString() {
|
||||
final String name = getLocationName();
|
||||
return name != null ? "(" + name + ")" : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon getIcon(final boolean open) {
|
||||
if (PyUtil.isPackage(PyFileImpl.this)) {
|
||||
return AllIcons.Modules.SourceFolder;
|
||||
}
|
||||
return PyFileImpl.this.getIcon(0);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String getModuleName(@NotNull PyFile file) {
|
||||
if (PyUtil.isPackage(file)) {
|
||||
final PsiDirectory dir = file.getContainingDirectory();
|
||||
if (dir != null) {
|
||||
return dir.getName();
|
||||
}
|
||||
}
|
||||
return FileUtil.getNameWithoutExtension(file.getName());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String getLocationName() {
|
||||
final QualifiedName name = QualifiedNameFinder.findShortestImportableQName(PyFileImpl.this);
|
||||
if (name != null) {
|
||||
final QualifiedName prefix = name.removeTail(1);
|
||||
if (prefix.getComponentCount() > 0) {
|
||||
return prefix.toString();
|
||||
}
|
||||
}
|
||||
final String relativePath = getRelativeContainerPath();
|
||||
if (relativePath != null) {
|
||||
return relativePath;
|
||||
}
|
||||
final PsiDirectory psiDirectory = getParent();
|
||||
if (psiDirectory != null) {
|
||||
return psiDirectory.getVirtualFile().getPresentableUrl();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String getRelativeContainerPath() {
|
||||
final PsiDirectory psiDirectory = getParent();
|
||||
if (psiDirectory != null) {
|
||||
final VirtualFile virtualFile = getVirtualFile();
|
||||
if (virtualFile != null) {
|
||||
final VirtualFile root = ProjectFileIndex.SERVICE.getInstance(getProject()).getContentRootForFile(virtualFile);
|
||||
if (root != null) {
|
||||
final VirtualFile parent = virtualFile.getParent();
|
||||
final VirtualFile rootParent = root.getParent();
|
||||
if (rootParent != null && parent != null) {
|
||||
return VfsUtilCore.getRelativePath(parent, rootParent, File.separatorChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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.jetbrains.python.psi.stubs;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.indexing.*;
|
||||
import com.intellij.util.io.EnumeratorStringDescriptor;
|
||||
import com.intellij.util.io.KeyDescriptor;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.PythonFileType;
|
||||
import com.jetbrains.python.psi.PyFile;
|
||||
import com.jetbrains.python.psi.search.PyProjectScopeBuilder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author vlan
|
||||
*/
|
||||
public class PyModuleNameIndex extends ScalarIndexExtension<String> {
|
||||
public static final ID<String, Void> NAME = ID.create("Py.module.name");
|
||||
|
||||
private final EnumeratorStringDescriptor myKeyDescriptor = new EnumeratorStringDescriptor();
|
||||
private final DataIndexer<String, Void, FileContent> myDataIndexer = new DataIndexer<String, Void, FileContent>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Map<String, Void> map(FileContent inputData) {
|
||||
final VirtualFile file = inputData.getFile();
|
||||
final String name = file.getName();
|
||||
if (PyNames.INIT_DOT_PY.equals(name)) {
|
||||
final VirtualFile parent = file.getParent();
|
||||
if (parent != null && parent.isDirectory()) {
|
||||
return Collections.singletonMap(parent.getName(), null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return Collections.singletonMap(FileUtil.getNameWithoutExtension(name), null);
|
||||
}
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ID<String, Void> getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DataIndexer<String, Void, FileContent> getIndexer() {
|
||||
return myDataIndexer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyDescriptor<String> getKeyDescriptor() {
|
||||
return myKeyDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileBasedIndex.InputFilter getInputFilter() {
|
||||
return new DefaultFileTypeSpecificInputFilter(PythonFileType.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dependsOnFileContent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVersion() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Collection<String> getAllKeys(@NotNull Project project) {
|
||||
return FileBasedIndex.getInstance().getAllKeys(NAME, project);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<PyFile> find(@NotNull String name, @NotNull Project project, boolean includeNonProjectItems) {
|
||||
final List<PyFile> results = new ArrayList<PyFile>();
|
||||
final GlobalSearchScope scope = includeNonProjectItems
|
||||
? PyProjectScopeBuilder.excludeSdkTestsScope(project)
|
||||
: GlobalSearchScope.projectScope(project);
|
||||
final Collection<VirtualFile> files = FileBasedIndex.getInstance().getContainingFiles(NAME, name, scope);
|
||||
for (VirtualFile virtualFile : files) {
|
||||
final PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
|
||||
if (psiFile instanceof PyFile) {
|
||||
results.add((PyFile)psiFile);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.jetbrains.python;
|
||||
|
||||
import com.jetbrains.python.fixtures.PyTestCase;
|
||||
import com.jetbrains.python.psi.stubs.PyModuleNameIndex;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author vlan
|
||||
*/
|
||||
public class PyIndexingTest extends PyTestCase {
|
||||
public static final String TEST_DIRECTORY = "indexing/";
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
final String testName = getTestName(false);
|
||||
myFixture.copyDirectoryToProject(TEST_DIRECTORY + testName, "");
|
||||
myFixture.configureFromTempProjectFile("a.py");
|
||||
}
|
||||
|
||||
public void testModuleNameIndex() {
|
||||
final Collection<String> modules = PyModuleNameIndex.getAllKeys(myFixture.getProject());
|
||||
assertContainsElements(modules, "foo");
|
||||
assertContainsElements(modules, "bar");
|
||||
assertDoesntContain(modules, "__init__");
|
||||
assertDoesntContain(modules, "baz");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user