mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-05 01:50:56 +07:00
restore resolve from Python to Java, introduce Java package type
This commit is contained in:
@@ -11,16 +11,10 @@ import org.jetbrains.annotations.Nullable;
|
||||
*/
|
||||
public class PyJavaImportResolver implements PyImportResolver {
|
||||
@Nullable
|
||||
public PsiElement resolveImportReference(final PyElement importElement, final String importText, PsiElement importFrom) {
|
||||
String fqn = importText;
|
||||
if (importFrom instanceof PsiDirectory) {
|
||||
PsiPackage fromPackage = JavaDirectoryService.getInstance().getPackage((PsiDirectory) importFrom);
|
||||
if (fromPackage != null) {
|
||||
importFrom = fromPackage;
|
||||
}
|
||||
}
|
||||
if (importFrom instanceof PsiPackage) {
|
||||
fqn = ((PsiPackage) importFrom).getQualifiedName() + "." + fqn;
|
||||
public PsiElement resolveImportReference(final PyElement importElement, final PyQualifiedName importText, PyQualifiedName importFrom) {
|
||||
String fqn = importText.toString();
|
||||
if (importFrom != null) {
|
||||
fqn = importFrom.toString() + "." + fqn;
|
||||
}
|
||||
|
||||
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(importElement.getProject());
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.jetbrains.python.psi.impl;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiPackage;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.ProjectScope;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.jetbrains.python.psi.AccessDirection;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.resolve.PyResolveContext;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class PyJavaPackageType implements PyType {
|
||||
private final PsiPackage myPackage;
|
||||
@Nullable private final Module myModule;
|
||||
|
||||
public PyJavaPackageType(PsiPackage aPackage, @Nullable Module module) {
|
||||
myPackage = aPackage;
|
||||
myModule = module;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends PsiElement> resolveMember(String name,
|
||||
@Nullable PyExpression location,
|
||||
AccessDirection direction,
|
||||
PyResolveContext resolveContext) {
|
||||
Project project = myPackage.getProject();
|
||||
JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
|
||||
String childName = myPackage.getQualifiedName() + "." + name;
|
||||
GlobalSearchScope scope = getScope(project);
|
||||
List<PsiElement> result = new ArrayList<PsiElement>();
|
||||
Collections.addAll(result, facade.findClasses(childName, scope));
|
||||
final PsiPackage psiPackage = facade.findPackage(childName);
|
||||
if (psiPackage != null) {
|
||||
result.add(psiPackage);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private GlobalSearchScope getScope(Project project) {
|
||||
return myModule != null ? myModule.getModuleWithDependenciesAndLibrariesScope(false) : ProjectScope.getAllScope(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getCompletionVariants(String completionPrefix, PyExpression location, ProcessingContext context) {
|
||||
List<Object> variants = new ArrayList<Object>();
|
||||
final GlobalSearchScope scope = getScope(location.getProject());
|
||||
final PsiClass[] classes = myPackage.getClasses(scope);
|
||||
for (PsiClass psiClass : classes) {
|
||||
variants.add(LookupElementBuilder.create(psiClass).setIcon(psiClass.getIcon(0)));
|
||||
}
|
||||
final PsiPackage[] subPackages = myPackage.getSubPackages(scope);
|
||||
for (PsiPackage subPackage : subPackages) {
|
||||
variants.add(LookupElementBuilder.create(subPackage).setIcon(subPackage.getIcon(0)));
|
||||
}
|
||||
return ArrayUtil.toObjectArray(variants);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return myPackage.getQualifiedName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltin() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.jetbrains.python.psi.impl;
|
||||
|
||||
import com.intellij.openapi.module.ModuleUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.Processor;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.PyNamedParameter;
|
||||
import com.jetbrains.python.psi.PyParameterList;
|
||||
import com.jetbrains.python.psi.PyReferenceExpression;
|
||||
import com.jetbrains.python.psi.search.PySuperMethodsSearch;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import com.jetbrains.python.psi.types.PyTypeProviderBase;
|
||||
@@ -21,10 +21,13 @@ import java.util.List;
|
||||
*/
|
||||
public class PyJavaTypeProvider extends PyTypeProviderBase {
|
||||
@Nullable
|
||||
public PyType getReferenceType(@NotNull final PsiElement referenceTarget, TypeEvalContext context) {
|
||||
public PyType getReferenceType(@NotNull final PsiElement referenceTarget, TypeEvalContext context, @Nullable PsiElement anchor) {
|
||||
if (referenceTarget instanceof PsiClass) {
|
||||
return new PyJavaClassType((PsiClass) referenceTarget);
|
||||
}
|
||||
if (referenceTarget instanceof PsiPackage) {
|
||||
return new PyJavaPackageType((PsiPackage) referenceTarget, anchor == null ? null : ModuleUtil.findModuleForPsiElement(anchor));
|
||||
}
|
||||
if (referenceTarget instanceof PsiMethod) {
|
||||
PsiMethod method = (PsiMethod) referenceTarget;
|
||||
final PsiType type = method.getReturnType();
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.jetbrains.jython;
|
||||
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.testFramework.ResolveTestCase;
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
@@ -42,6 +40,24 @@ public class PyToJavaResolveTest extends ResolveTestCase {
|
||||
Assert.assertEquals("java.util.List", ((PsiMethod) target).getContainingClass().getQualifiedName());
|
||||
}
|
||||
|
||||
public void testPackageType() throws Exception {
|
||||
PsiElement target = resolve();
|
||||
Assert.assertTrue(target instanceof PsiClass);
|
||||
Assert.assertEquals("java.util.ArrayList", ((PsiClass) target).getQualifiedName());
|
||||
}
|
||||
|
||||
public void testJavaPackage() throws Exception {
|
||||
PsiElement target = resolve();
|
||||
Assert.assertTrue(target instanceof PsiPackage);
|
||||
Assert.assertEquals("java", ((PsiPackage) target).getQualifiedName());
|
||||
}
|
||||
|
||||
public void testJavaLangPackage() throws Exception {
|
||||
PsiElement target = resolve();
|
||||
Assert.assertTrue(target instanceof PsiPackage);
|
||||
Assert.assertEquals("java.lang", ((PsiPackage) target).getQualifiedName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return PythonTestUtil.getTestDataPath() + "/resolve/pyToJava/";
|
||||
|
||||
@@ -99,7 +99,7 @@ public class PyCallExpressionImpl extends PyElementImpl implements PyCallExpress
|
||||
return new PyClassType(((PyFunction)target).getContainingClass(), false); // resolved to __init__, back to class
|
||||
}
|
||||
// TODO: look at well-known functions and their return types
|
||||
final PyType providedType = PyReferenceExpressionImpl.getReferenceTypeFromProviders(target, context);
|
||||
final PyType providedType = PyReferenceExpressionImpl.getReferenceTypeFromProviders(target, context, this);
|
||||
if (providedType != null) {
|
||||
return providedType;
|
||||
}
|
||||
|
||||
@@ -12,5 +12,5 @@ public interface PyImportResolver {
|
||||
ExtensionPointName<PyImportResolver> EP_NAME = ExtensionPointName.create("Pythonid.importResolver");
|
||||
|
||||
@Nullable
|
||||
PsiElement resolveImportReference(PyElement importElement, String importText, final PsiElement importFrom);
|
||||
PsiElement resolveImportReference(PyElement importElement, PyQualifiedName importText, PyQualifiedName importFrom);
|
||||
}
|
||||
|
||||
@@ -279,7 +279,7 @@ public class PyReferenceExpressionImpl extends PyElementImpl implements PyRefere
|
||||
public static PyType getTypeFromTarget(@NotNull final PsiElement target,
|
||||
final TypeEvalContext context,
|
||||
@Nullable PyReferenceExpression anchor) {
|
||||
final PyType pyType = getReferenceTypeFromProviders(target, context);
|
||||
final PyType pyType = getReferenceTypeFromProviders(target, context, anchor);
|
||||
if (pyType != null) {
|
||||
return pyType;
|
||||
}
|
||||
@@ -350,9 +350,11 @@ public class PyReferenceExpressionImpl extends PyElementImpl implements PyRefere
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PyType getReferenceTypeFromProviders(@NotNull final PsiElement target, TypeEvalContext context) {
|
||||
public static PyType getReferenceTypeFromProviders(@NotNull final PsiElement target,
|
||||
TypeEvalContext context,
|
||||
@Nullable PsiElement anchor) {
|
||||
for (PyTypeProvider provider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) {
|
||||
final PyType result = provider.getReferenceType(target, context);
|
||||
final PyType result = provider.getReferenceType(target, context, anchor);
|
||||
if (result != null) return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ public interface PyTypeProvider {
|
||||
PyType getReferenceExpressionType(PyReferenceExpression referenceExpression, TypeEvalContext context);
|
||||
|
||||
@Nullable
|
||||
PyType getReferenceType(@NotNull PsiElement referenceTarget, TypeEvalContext context);
|
||||
PyType getReferenceType(@NotNull PsiElement referenceTarget, TypeEvalContext context, @Nullable PsiElement anchor);
|
||||
|
||||
@Nullable
|
||||
PyType getParameterType(PyNamedParameter param, final PyFunction func, TypeEvalContext context);
|
||||
|
||||
@@ -138,16 +138,14 @@ public class ResolveImportUtil {
|
||||
}
|
||||
}
|
||||
else if (importStatement instanceof PyImportStatement) { // "import foo"
|
||||
return resolveModule(qName, file, absolute_import_enabled, 0);
|
||||
final List<PsiElement> result = resolveModule(qName, file, absolute_import_enabled, 0);
|
||||
if (result.size() > 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// in-python resolution failed
|
||||
if (moduleQName != null) {
|
||||
final List<PsiElement> importFrom = resolveModule(moduleQName, file, false, 0);
|
||||
final PsiElement result = resolveForeignImport(import_element, StringUtil.join(qName.getComponents(), "."),
|
||||
importFrom.isEmpty() ? null : importFrom.get(0));
|
||||
return result != null ? Collections.singletonList(result) : Collections.<PsiElement>emptyList();
|
||||
}
|
||||
return Collections.emptyList();
|
||||
final PsiElement result = resolveForeignImport(import_element, qName, moduleQName);
|
||||
return result != null ? Collections.singletonList(result) : Collections.<PsiElement>emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -500,7 +498,7 @@ public class ResolveImportUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiElement resolveForeignImport(final PyElement importElement, final String importText, final PsiElement importFrom) {
|
||||
private static PsiElement resolveForeignImport(final PyElement importElement, final PyQualifiedName importText, final PyQualifiedName importFrom) {
|
||||
for (PyImportResolver resolver : Extensions.getExtensions(PyImportResolver.EP_NAME)) {
|
||||
PsiElement result = resolver.resolveImportReference(importElement, importText, importFrom);
|
||||
if (result != null) {
|
||||
|
||||
@@ -69,7 +69,7 @@ public class PyTypeProviderBase implements PyTypeProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PyType getReferenceType(@NotNull PsiElement referenceTarget, TypeEvalContext context) {
|
||||
public PyType getReferenceType(@NotNull PsiElement referenceTarget, TypeEvalContext context, @Nullable PsiElement anchor) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
3
python/testData/resolve/pyToJava/JavaLangPackage.py
Normal file
3
python/testData/resolve/pyToJava/JavaLangPackage.py
Normal file
@@ -0,0 +1,3 @@
|
||||
import java
|
||||
|
||||
java.la<ref>ng.System.out
|
||||
1
python/testData/resolve/pyToJava/JavaPackage.py
Normal file
1
python/testData/resolve/pyToJava/JavaPackage.py
Normal file
@@ -0,0 +1 @@
|
||||
import ja<ref>va
|
||||
4
python/testData/resolve/pyToJava/PackageType.py
Normal file
4
python/testData/resolve/pyToJava/PackageType.py
Normal file
@@ -0,0 +1,4 @@
|
||||
import java
|
||||
from java import util
|
||||
|
||||
l = util.ArrayLi<ref>st()
|
||||
Reference in New Issue
Block a user