mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-09 16:39:37 +07:00
CPP-434 Split [python-community-plugin] into [python-community-core-plugin] and [python-community-java-plugin]
This commit is contained in:
10
python/pluginJava/META-INF/python-community-plugin-java.xml
Normal file
10
python/pluginJava/META-INF/python-community-plugin-java.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<idea-plugin version="2">
|
||||
<!-- Components and extensions declared in this file work ONLY in the Python plugin,
|
||||
both Community and Professional versions. -->
|
||||
<extensions defaultExtensionNs="Pythonid">
|
||||
<importResolver implementation="com.jetbrains.python.psi.impl.PyJavaImportResolver"/>
|
||||
<typeProvider implementation="com.jetbrains.python.psi.impl.PyJavaTypeProvider"/>
|
||||
<pySuperMethodsSearch implementation="com.jetbrains.python.psi.impl.PyJavaSuperMethodsSearchExecutor"/>
|
||||
<importCandidateProvider implementation="com.jetbrains.python.psi.impl.PyJavaImportCandidateProvider"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import com.intellij.codeInsight.completion.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.intellij.patterns.PlatformPatterns.psiElement;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class PyConstructorArgumentCompletionContributor extends CompletionContributor {
|
||||
public PyConstructorArgumentCompletionContributor() {
|
||||
extend(CompletionType.BASIC,
|
||||
psiElement()
|
||||
.withParents(PyReferenceExpression.class, PyArgumentList.class, PyCallExpression.class),
|
||||
new CompletionProvider<CompletionParameters>() {
|
||||
@Override
|
||||
protected void addCompletions(@NotNull CompletionParameters parameters,
|
||||
ProcessingContext context,
|
||||
@NotNull CompletionResultSet result) {
|
||||
final PyCallExpression call = PsiTreeUtil.getParentOfType(parameters.getOriginalPosition(), PyCallExpression.class);
|
||||
if (call == null) return;
|
||||
final PyExpression calleeExpression = call.getCallee();
|
||||
if (calleeExpression instanceof PyReferenceExpression) {
|
||||
final PsiElement callee = ((PyReferenceExpression)calleeExpression).getReference().resolve();
|
||||
if (callee instanceof PsiClass) {
|
||||
addSettersAndListeners(result, (PsiClass)callee);
|
||||
}
|
||||
else if (callee instanceof PsiMethod && ((PsiMethod) callee).isConstructor()) {
|
||||
final PsiClass containingClass = ((PsiMethod)callee).getContainingClass();
|
||||
assert containingClass != null;
|
||||
addSettersAndListeners(result, containingClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void addSettersAndListeners(CompletionResultSet result, PsiClass containingClass) {
|
||||
// see PyJavaType.init() in Jython source code for matching logic
|
||||
for (PsiMethod method : containingClass.getAllMethods()) {
|
||||
final Project project = containingClass.getProject();
|
||||
if (PropertyUtil.isSimplePropertySetter(method)) {
|
||||
final String propName = PropertyUtil.getPropertyName(method);
|
||||
result.addElement(PyUtil.createNamedParameterLookup(propName, project));
|
||||
}
|
||||
else if (method.getName().startsWith("add") && method.getName().endsWith("Listener") && PsiType.VOID.equals(method.getReturnType())) {
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
if (parameters.length == 1) {
|
||||
final PsiType type = parameters[0].getType();
|
||||
if (type instanceof PsiClassType) {
|
||||
final PsiClass parameterClass = ((PsiClassType)type).resolve();
|
||||
if (parameterClass != null) {
|
||||
result.addElement(PyUtil.createNamedParameterLookup(StringUtil.decapitalize(parameterClass.getName()), project));
|
||||
for (PsiMethod parameterMethod : parameterClass.getMethods()) {
|
||||
result.addElement(PyUtil.createNamedParameterLookup(parameterMethod.getName(), project));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.intellij.util.Processor;
|
||||
import com.jetbrains.python.psi.AccessDirection;
|
||||
import com.jetbrains.python.psi.PyCallSiteExpression;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.resolve.CompletionVariantsProcessor;
|
||||
import com.jetbrains.python.psi.resolve.PyResolveContext;
|
||||
import com.jetbrains.python.psi.resolve.RatedResolveResult;
|
||||
import com.jetbrains.python.psi.types.PyCallableParameter;
|
||||
import com.jetbrains.python.psi.types.PyClassLikeType;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class PyJavaClassType implements PyClassLikeType {
|
||||
private final PsiClass myClass;
|
||||
private final boolean myDefinition;
|
||||
|
||||
public PyJavaClassType(final PsiClass aClass, boolean definition) {
|
||||
myClass = aClass;
|
||||
myDefinition = definition;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<? extends RatedResolveResult> resolveMember(@NotNull final String name,
|
||||
PyExpression location,
|
||||
@NotNull AccessDirection direction,
|
||||
@NotNull PyResolveContext resolveContext) {
|
||||
return resolveMember(name, location, direction, resolveContext, true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<? extends RatedResolveResult> resolveMember(@NotNull String name,
|
||||
@Nullable PyExpression location,
|
||||
@NotNull AccessDirection direction,
|
||||
@NotNull PyResolveContext resolveContext,
|
||||
boolean inherited) {
|
||||
final PsiMethod[] methods = myClass.findMethodsByName(name, inherited);
|
||||
if (methods.length > 0) {
|
||||
ResolveResultList resultList = new ResolveResultList();
|
||||
for (PsiMethod method : methods) {
|
||||
resultList.poke(method, RatedResolveResult.RATE_NORMAL);
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
final PsiField field = myClass.findFieldByName(name, inherited);
|
||||
if (field != null) return ResolveResultList.to(field);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object[] getCompletionVariants(String completionPrefix, PsiElement location, ProcessingContext context) {
|
||||
final CompletionVariantsProcessor processor = new CompletionVariantsProcessor(location);
|
||||
myClass.processDeclarations(processor, ResolveState.initial(), null, location);
|
||||
return processor.getResult();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
if (myClass != null) {
|
||||
return myClass.getName();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltin() {
|
||||
return false; // TODO: JDK's types could be considered built-in.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assertValid(String message) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCallable() {
|
||||
return myDefinition;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PyType getReturnType(@NotNull TypeEvalContext context) {
|
||||
if (myDefinition) {
|
||||
return new PyJavaClassType(myClass, false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyCallSiteExpression callSite) {
|
||||
return getReturnType(context);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<PyCallableParameter> getParameters(@NotNull TypeEvalContext context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefinition() {
|
||||
return myDefinition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PyClassLikeType toInstance() {
|
||||
return myDefinition ? new PyJavaClassType(myClass, false) : this;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getClassQName() {
|
||||
return myClass.getQualifiedName();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<PyClassLikeType> getSuperClassTypes(@NotNull TypeEvalContext context) {
|
||||
final List<PyClassLikeType> result = new ArrayList<PyClassLikeType>();
|
||||
for (PsiClass cls : myClass.getSupers()) {
|
||||
result.add(new PyJavaClassType(cls, myDefinition));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMembers(@NotNull final Processor<PsiElement> processor, final boolean inherited, @NotNull TypeEvalContext context) {
|
||||
// TODO: Implement
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<PyClassLikeType> getAncestorTypes(@NotNull final TypeEvalContext context) {
|
||||
// TODO: Implement
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return myClass.isValid();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PyClassLikeType getMetaClassType(@NotNull TypeEvalContext context, boolean inherited) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public PsiClass getPsiClass() {
|
||||
return myClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof PyJavaClassType)) return false;
|
||||
|
||||
PyJavaClassType type = (PyJavaClassType)o;
|
||||
|
||||
if (myDefinition != type.myDefinition) return false;
|
||||
if (myClass != null ? !myClass.equals(type.myClass) : type.myClass != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = myClass != null ? myClass.hashCode() : 0;
|
||||
result = 31 * result + (myDefinition ? 1 : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.ProjectScope;
|
||||
import com.intellij.psi.search.PsiShortNamesCache;
|
||||
import com.intellij.psi.util.QualifiedName;
|
||||
import com.jetbrains.python.codeInsight.imports.AutoImportQuickFix;
|
||||
import com.jetbrains.python.codeInsight.imports.PyImportCandidateProvider;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class PyJavaImportCandidateProvider implements PyImportCandidateProvider {
|
||||
@Override
|
||||
public void addImportCandidates(PsiReference reference, String name, AutoImportQuickFix quickFix) {
|
||||
final PsiElement element = reference.getElement();
|
||||
final Project project = element.getProject();
|
||||
Module module = ModuleUtil.findModuleForPsiElement(element);
|
||||
GlobalSearchScope scope = module == null ? ProjectScope.getAllScope(project) : module.getModuleWithDependenciesAndLibrariesScope(false);
|
||||
PsiShortNamesCache cache = PsiShortNamesCache.getInstance(project);
|
||||
final PsiClass[] classesByName = cache.getClassesByName(name, scope);
|
||||
for (PsiClass psiClass : classesByName) {
|
||||
final QualifiedName packageQName = QualifiedName.fromDottedString(psiClass.getQualifiedName()).removeLastComponent();
|
||||
quickFix.addImport(psiClass, psiClass.getContainingFile(), packageQName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiPackage;
|
||||
import com.intellij.psi.util.QualifiedName;
|
||||
import com.jetbrains.python.psi.resolve.QualifiedNameResolveContext;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class PyJavaImportResolver implements PyImportResolver {
|
||||
@Nullable
|
||||
public PsiElement resolveImportReference(QualifiedName name, QualifiedNameResolveContext context, boolean withRoots) {
|
||||
String fqn = name.toString();
|
||||
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(context.getProject());
|
||||
final PsiPackage aPackage = psiFacade.findPackage(fqn);
|
||||
if (aPackage != null) {
|
||||
return aPackage;
|
||||
}
|
||||
|
||||
Module module = context.getModule();
|
||||
if (module != null) {
|
||||
final PsiClass aClass = psiFacade.findClass(fqn, module.getModuleWithDependenciesAndLibrariesScope(false));
|
||||
if (aClass != null) return aClass;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.jetbrains.python.psi.AccessDirection;
|
||||
import com.jetbrains.python.psi.PyCallSiteExpression;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.resolve.PyResolveContext;
|
||||
import com.jetbrains.python.psi.resolve.RatedResolveResult;
|
||||
import com.jetbrains.python.psi.types.PyCallableParameter;
|
||||
import com.jetbrains.python.psi.types.PyCallableType;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class PyJavaMethodType implements PyCallableType {
|
||||
private final PsiMethod myMethod;
|
||||
|
||||
public PyJavaMethodType(PsiMethod method) {
|
||||
myMethod = method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCallable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PyType getReturnType(@NotNull TypeEvalContext context) {
|
||||
return PyJavaTypeProvider.asPyType(myMethod.getReturnType());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyCallSiteExpression callSite) {
|
||||
return getReturnType(context);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<PyCallableParameter> getParameters(@NotNull TypeEvalContext context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<? extends RatedResolveResult> resolveMember(@NotNull String name,
|
||||
@Nullable PyExpression location,
|
||||
@NotNull AccessDirection direction,
|
||||
@NotNull PyResolveContext resolveContext) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getCompletionVariants(String completionPrefix, PsiElement location, ProcessingContext context) {
|
||||
return ArrayUtil.EMPTY_OBJECT_ARRAY;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getName() {
|
||||
final PsiClass cls = myMethod.getContainingClass();
|
||||
return "Java method(" + (cls != null ? cls.getQualifiedName() : cls) + "." + myMethod.getName() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltin() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assertValid(String message) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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.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.resolve.RatedResolveResult;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
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 RatedResolveResult> resolveMember(@NotNull String name,
|
||||
@Nullable PyExpression location,
|
||||
@NotNull AccessDirection direction,
|
||||
@NotNull PyResolveContext resolveContext) {
|
||||
Project project = myPackage.getProject();
|
||||
JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
|
||||
String childName = myPackage.getQualifiedName() + "." + name;
|
||||
GlobalSearchScope scope = getScope(project);
|
||||
ResolveResultList result = new ResolveResultList();
|
||||
final PsiClass[] classes = facade.findClasses(childName, scope);
|
||||
for (PsiClass aClass : classes) {
|
||||
result.poke(aClass, RatedResolveResult.RATE_NORMAL);
|
||||
}
|
||||
final PsiPackage psiPackage = facade.findPackage(childName);
|
||||
if (psiPackage != null) {
|
||||
result.poke(psiPackage, RatedResolveResult.RATE_NORMAL);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private GlobalSearchScope getScope(Project project) {
|
||||
return myModule != null ? myModule.getModuleWithDependenciesAndLibrariesScope(false) : ProjectScope.getAllScope(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getCompletionVariants(String completionPrefix, PsiElement 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).withIcon(psiClass.getIcon(0)));
|
||||
}
|
||||
final PsiPackage[] subPackages = myPackage.getSubPackages(scope);
|
||||
for (PsiPackage subPackage : subPackages) {
|
||||
variants.add(LookupElementBuilder.create(subPackage).withIcon(subPackage.getIcon(0)));
|
||||
}
|
||||
return ArrayUtil.toObjectArray(variants);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return myPackage.getQualifiedName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltin() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assertValid(String message) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.QueryExecutor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.search.PySuperMethodsSearch;
|
||||
import com.jetbrains.python.psi.types.PyClassLikeType;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class PyJavaSuperMethodsSearchExecutor implements QueryExecutor<PsiElement, PySuperMethodsSearch.SearchParameters> {
|
||||
public boolean execute(@NotNull final PySuperMethodsSearch.SearchParameters queryParameters, @NotNull final Processor<PsiElement> consumer) {
|
||||
PyFunction func = queryParameters.getDerivedMethod();
|
||||
PyClass containingClass = func.getContainingClass();
|
||||
if (containingClass != null) {
|
||||
for (PyClassLikeType type : containingClass.getSuperClassTypes(TypeEvalContext.codeInsightFallback(containingClass.getProject()))) {
|
||||
if (type instanceof PyJavaClassType) {
|
||||
final PsiClass psiClass = ((PyJavaClassType)type).getPsiClass();
|
||||
PsiMethod[] methods = psiClass.findMethodsByName(func.getName(), true);
|
||||
// the Python method actually does override/implement all of Java super methods with the same name
|
||||
if (!ContainerUtil.process(methods, consumer)) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import com.intellij.openapi.module.ModuleUtil;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
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.search.PySuperMethodsSearch;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import com.jetbrains.python.psi.types.PyTypeProviderBase;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class PyJavaTypeProvider extends PyTypeProviderBase {
|
||||
@Nullable
|
||||
public PyType getReferenceType(@NotNull final PsiElement referenceTarget, TypeEvalContext context, @Nullable PsiElement anchor) {
|
||||
if (referenceTarget instanceof PsiClass) {
|
||||
return new PyJavaClassType((PsiClass) referenceTarget, true);
|
||||
}
|
||||
if (referenceTarget instanceof PsiPackage) {
|
||||
return new PyJavaPackageType((PsiPackage) referenceTarget, anchor == null ? null : ModuleUtil.findModuleForPsiElement(anchor));
|
||||
}
|
||||
if (referenceTarget instanceof PsiMethod) {
|
||||
PsiMethod method = (PsiMethod) referenceTarget;
|
||||
return new PyJavaMethodType(method);
|
||||
}
|
||||
if (referenceTarget instanceof PsiField) {
|
||||
return asPyType(((PsiField)referenceTarget).getType());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PyType asPyType(PsiType type) {
|
||||
if (type instanceof PsiClassType) {
|
||||
final PsiClassType classType = (PsiClassType)type;
|
||||
final PsiClass psiClass = classType.resolve();
|
||||
if (psiClass != null) {
|
||||
return new PyJavaClassType(psiClass, false);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Ref<PyType> getParameterType(@NotNull final PyNamedParameter param,
|
||||
@NotNull final PyFunction func,
|
||||
@NotNull TypeEvalContext context) {
|
||||
if (!(param.getParent() instanceof PyParameterList)) return null;
|
||||
List<PyNamedParameter> params = ParamHelper.collectNamedParameters((PyParameterList) param.getParent());
|
||||
final int index = params.indexOf(param);
|
||||
if (index < 0) return null;
|
||||
final List<PyType> superMethodParameterTypes = new ArrayList<PyType>();
|
||||
PySuperMethodsSearch.search(func, context).forEach(new Processor<PsiElement>() {
|
||||
public boolean process(final PsiElement psiElement) {
|
||||
if (psiElement instanceof PsiMethod) {
|
||||
final PsiMethod method = (PsiMethod)psiElement;
|
||||
final PsiParameter[] psiParameters = method.getParameterList().getParameters();
|
||||
int javaIndex = method.hasModifierProperty(PsiModifier.STATIC) ? index : index-1; // adjust for 'self' parameter
|
||||
if (javaIndex < psiParameters.length) {
|
||||
PsiType paramType = psiParameters [javaIndex].getType();
|
||||
if (paramType instanceof PsiClassType) {
|
||||
final PsiClass psiClass = ((PsiClassType)paramType).resolve();
|
||||
if (psiClass != null) {
|
||||
superMethodParameterTypes.add(new PyJavaClassType(psiClass, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (superMethodParameterTypes.size() > 0) {
|
||||
final PyType type = superMethodParameterTypes.get(0);
|
||||
if (type != null) {
|
||||
return Ref.create(type);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
16
python/pluginJava/python-community-plugin-java.iml
Normal file
16
python/pluginJava/python-community-plugin-java.iml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="lang-api" />
|
||||
<orderEntry type="module" module-name="java-psi-api" />
|
||||
<orderEntry type="module" module-name="python-psi-api" />
|
||||
<orderEntry type="module" module-name="python-community" />
|
||||
<orderEntry type="module" module-name="java-indexing-api" />
|
||||
</component>
|
||||
</module>
|
||||
Reference in New Issue
Block a user