blob: 2a74a7342efc6cf09de617c55db1097be6c65529 [file] [log] [blame]
/*
* Copyright 2000-2013 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.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 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).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) {
return superMethodParameterTypes.get(0);
}
return null;
}
}