return ((PyFile) parent).findTopLevelFunction(myFunctionName);
}
if (parent instanceof PyClass) {
- return ((PyClass) parent).findMethodByName(myFunctionName, false);
+ return ((PyClass) parent).findMethodByName(myFunctionName, false, null);
}
for (PsiElement element : parent.getChildren()) {
if (element instanceof PyFunction && myFunctionName.equals(((PyFunction)element).getName())) {
if (!(parent instanceof PyClass)) {
return null;
}
- return ((PyClass)parent).findClassAttribute(myAttributeName, true);
+ return ((PyClass)parent).findClassAttribute(myAttributeName, true, null);
}
}
*
* @param name what to look for
* @param inherited true: search in superclasses; false: only look for methods defined in this class.
+ * @param context
* @return
*/
@Nullable
- PyFunction findMethodByName(@Nullable @NonNls final String name, boolean inherited);
+ PyFunction findMethodByName(@Nullable @NonNls final String name, boolean inherited, TypeEvalContext context);
/**
* Finds either __init__ or __new__, whichever is defined for given class.
List<PyTargetExpression> getClassAttributesInherited(@NotNull TypeEvalContext context);
@Nullable
- PyTargetExpression findClassAttribute(@NotNull String name, boolean inherited);
+ PyTargetExpression findClassAttribute(@NotNull String name, boolean inherited, TypeEvalContext context);
/**
* Effectively collects assignments to attributes of {@code self} in {@code __init__}, {@code __new__} and
final String memberName = StringUtil.getShortName(fqn, '#');
final PyClass nestedClass = aClass.findNestedClass(memberName, false);
if (nestedClass != null) return nestedClass;
- final PyFunction methodByName = aClass.findMethodByName(memberName, false);
+ final PyFunction methodByName = aClass.findMethodByName(memberName, false, null);
if (methodByName != null) return methodByName;
}
}
}
final List<PyTargetExpression> result = new ArrayList<PyTargetExpression>();
for (PyClass aClass: pyClass.getAncestorClasses(null)) {
- final PyTargetExpression superAttr = aClass.findClassAttribute(name, false);
+ final PyTargetExpression superAttr = aClass.findClassAttribute(name, false, null);
if (superAttr != null) {
result.add(superAttr);
}
}
final List<PyFunction> result = new ArrayList<PyFunction>();
for (PyClass aClass: pyClass.getAncestorClasses(null)) {
- final PyFunction byName = aClass.findMethodByName(name, false);
+ final PyFunction byName = aClass.findMethodByName(name, false, null);
if (byName != null) {
result.add(byName);
}
builder.append("Has overridden methods");
return false;
}
- if (pyClass.findMethodByName(pyFunction.getName(), false) != null) {
+ if (pyClass.findMethodByName(pyFunction.getName(), false, null) != null) {
builder.append("<br> ").append(pyClass.getName());
}
return true;
PyClass containingClass = PsiTreeUtil.getParentOfType(elt, PyClass.class);
if (containingClass != null && elt instanceof PyTargetExpression) {
for (PyClass ancestor : containingClass.getAncestorClasses(null)) {
- final PyTargetExpression attribute = ancestor.findClassAttribute(((PyTargetExpression)elt).getReferencedName(), false);
+ final PyTargetExpression attribute = ancestor.findClassAttribute(((PyTargetExpression)elt).getReferencedName(), false, null);
if (attribute != null) {
result.add(attribute);
}
if (PyNames.INIT.equals(function.getName())) {
return null;
}
- final TypeEvalContext context = TypeEvalContext.codeAnalysis(element.getProject(), null);
+ final TypeEvalContext context = TypeEvalContext.codeAnalysis(element.getProject(), (function != null ? function.getContainingFile() : null));
final PsiElement superMethod = PySuperMethodsSearch.search(function, context).findFirst();
if (superMethod != null) {
PyClass superClass = null;
if (containingClass == null) return null;
for (PyClass ancestor : containingClass
.getAncestorClasses(TypeEvalContext.codeAnalysis(element.getProject(), element.getContainingFile()))) {
- final PyTargetExpression ancestorAttr = ancestor.findClassAttribute(name, false);
+ final PyTargetExpression ancestorAttr = ancestor.findClassAttribute(name, false, null);
if (ancestorAttr != null) {
return new LineMarkerInfo<PsiElement>(element, element.getTextRange().getStartOffset(),
AllIcons.Gutter.OverridingMethod, Pass.UPDATE_ALL,
public boolean process(final PyClass inheritor) {
for (Iterator<PyFunction> it = candidates.get(pyClass).iterator(); it.hasNext(); ) {
PyFunction func = it.next();
- if (inheritor.findMethodByName(func.getName(), false) != null) {
+ if (inheritor.findMethodByName(func.getName(), false, null) != null) {
overridden.add(func);
it.remove();
}
if (name == null || PyUtil.isClassPrivateName(name)) {
continue;
}
- if (pyClass.findMethodByName(name, false) == null) {
+ if (pyClass.findMethodByName(name, false, null) == null) {
final PyMethodMember member = new PyMethodMember(function);
elements.add(member);
}
if (!PyNames.INIT.equals(baseFunction.getName()) && context.getReturnType(baseFunction) != PyNoneType.INSTANCE || overridingNew) {
statementBody.append("return ");
}
- if (baseClass.isNewStyleClass(null)) {
+ if (baseClass.isNewStyleClass(context)) {
statementBody.append(PyNames.SUPER);
statementBody.append("(");
final LanguageLevel langLevel = ((PyFile)pyClass.getContainingFile()).getLanguageLevel();
}
public static PsiElement findClassMember(@NotNull PyClass cls, @NotNull String name, boolean isDefinition) {
- final PyFunction function = cls.findMethodByName(name, false);
+ final PyFunction function = cls.findMethodByName(name, false, null);
if (function != null) {
final PyUtil.MethodFlags methodFlags = PyUtil.MethodFlags.of(function);
final boolean instanceMethod = methodFlags == null || methodFlags.isInstanceMethod();
return instanceAttribute;
}
}
- final PyTargetExpression classAttribute = cls.findClassAttribute(name, false);
+ final PyTargetExpression classAttribute = cls.findClassAttribute(name, false, null);
if (classAttribute != null) {
return classAttribute;
}
isFromClass = true;
}
else {
- inherited = ancestor.findMethodByName(methodName, false);
+ inherited = ancestor.findMethodByName(methodName, false, null);
}
if (inherited != null) {
docstringElement = inherited.getDocStringExpression();
final PyClassType objectType = PyBuiltinCache.getInstance(fun).getObjectType(); // old- and new-style classes share the __xxx__ stuff
if (objectType != null) {
final PyClass objectClass = objectType.getPyClass();
- final PyFunction predefinedMethod = objectClass.findMethodByName(mothodName, false);
+ final PyFunction predefinedMethod = objectClass.findMethodByName(mothodName, false, null);
if (predefinedMethod != null) {
final PyStringLiteralExpression predefinedDocstring = predefinedMethod.getDocStringExpression();
final String predefinedDoc = predefinedDocstring != null ? predefinedDocstring.getStringValue() : null;
return resolveParameter((PyFunction)owner);
}
if (owner instanceof PyClass) {
- final PyFunction init = ((PyClass)owner).findMethodByName(PyNames.INIT, false);
+ final PyFunction init = ((PyClass)owner).findMethodByName(PyNames.INIT, false, null);
if (init != null) {
PsiElement element = resolveParameter(init);
if (element == null && (myType.equals(ReferenceType.CLASS_VARIABLE) ||
@NotNull
@Override
public PsiElement[] getSecondaryElements() {
- final PyFunction initMethod = myClass.findMethodByName(PyNames.INIT, false);
+ final PyFunction initMethod = myClass.findMethodByName(PyNames.INIT, false, null);
if (initMethod != null) {
return new PsiElement[] { initMethod };
}
private static boolean isAbstractMethodForClass(@NotNull PyFunction method, @NotNull PyClass cls) {
final String methodName = method.getName();
if (methodName == null ||
- cls.findMethodByName(methodName, false) != null ||
- cls.findClassAttribute(methodName, false) != null) {
+ cls.findMethodByName(methodName, false, null) != null ||
+ cls.findClassAttribute(methodName, false, null) != null) {
return false;
}
return PyUtil.isDecoratedAsAbstract(method) || PyOverrideImplementUtil.raisesNotImplementedError(method);
attributesInInit.put(classAttr.getName(), classAttr);
}
- final PyFunction initMethod = containingClass.findMethodByName(PyNames.INIT, false);
+ final PyFunction initMethod = containingClass.findMethodByName(PyNames.INIT, false, null);
if (initMethod != null) {
PyClassImpl.collectInstanceAttributes(initMethod, attributesInInit);
}
for (PyClass superClass : containingClass.getAncestorClasses(myTypeEvalContext)) {
- final PyFunction superInit = superClass.findMethodByName(PyNames.INIT, false);
+ final PyFunction superInit = superClass.findMethodByName(PyNames.INIT, false, null);
if (superInit != null)
PyClassImpl.collectInstanceAttributes(superInit, attributesInInit);
if (cls == null) return;
if (!cls.isNewStyleClass(null)) return;
final String complementaryName = PyNames.NEW.equals(functionName) ? PyNames.INIT : PyNames.NEW;
- final PyFunction complementaryMethod = cls.findMethodByName(complementaryName, true);
+ final PyFunction complementaryMethod = cls.findMethodByName(complementaryName, true, null);
if (complementaryMethod == null || PyUtil.isObjectClass(assertNotNull(complementaryMethod.getContainingClass()))) return;
if (!PyUtil.isSignatureCompatibleTo(complementaryMethod, node, myTypeEvalContext) &&
!PyUtil.isSignatureCompatibleTo(node, complementaryMethod, myTypeEvalContext) &&
return;
if (!superHasConstructor(node)) return;
- PyFunction initMethod = node.findMethodByName(INIT, false);
+ PyFunction initMethod = node.findMethodByName(INIT, false, null);
if (initMethod != null) {
if (isExceptionClass(node, myTypeEvalContext) || hasConstructorCall(node, initMethod)) {
return;
final String className = cls.getName();
for (PyClass c : cls.getAncestorClasses(myTypeEvalContext)) {
final String name = c.getName();
- if (!PyUtil.isObjectClass(c) && !Comparing.equal(className, name) && c.findMethodByName(INIT, false) != null) {
+ if (!PyUtil.isObjectClass(c) && !Comparing.equal(className, name) && c.findMethodByName(INIT, false, null) != null) {
return true;
}
}
property = myPropertyCache.get(key);
}
else {
- property = cls.findProperty(name, true, null);
+ property = cls.findProperty(name, true, myTypeEvalContext);
}
myPropertyCache.put(key, property); // we store nulls, too, to know that a property does not exist
if (property != null) {
// reference signatures
PyClass objectClass = builtins.getClass("object");
if (objectClass != null) {
- final PyFunction methodRepr = objectClass.findMethodByName("__repr__", false);
+ final PyFunction methodRepr = objectClass.findMethodByName("__repr__", false, null);
if (methodRepr != null) myOneParamFunction = methodRepr;
- final PyFunction methodDelattr = objectClass.findMethodByName("__delattr__", false);
+ final PyFunction methodDelattr = objectClass.findMethodByName("__delattr__", false, null);
if (methodDelattr != null) myTwoParamFunction = methodDelattr;
}
}
else {
final PyClassType type = as(myTypeEvalContext.getType(rightExpression), PyClassType.class);
if (type != null) {
- if (myUsedMappingKeys.size() > 0 && !PyABCUtil.isSubclass(type.getPyClass(), PyNames.MAPPING)) {
+ if (myUsedMappingKeys.size() > 0 && !PyABCUtil.isSubclass(type.getPyClass(), PyNames.MAPPING, null)) {
registerProblem(rightExpression, PyBundle.message("INSP.format.requires.mapping"));
return;
}
if (superClasses.length == 0) return;
final PyClass superClass = superClasses[0];
- final PyFunction superInit = superClass.findMethodByName(PyNames.INIT, true);
+ final PyFunction superInit = superClass.findMethodByName(PyNames.INIT, true, null);
if (superInit == null) return;
final ParametersInfo origInfo = new ParametersInfo(problemFunction.getParameterList());
@Nullable
public static PsiElement addFieldToInit(Project project, PyClass cls, String itemName, Function<String, PyStatement> callback) {
if (cls != null && itemName != null) {
- PyFunction init = cls.findMethodByName(PyNames.INIT, false);
+ PyFunction init = cls.findMethodByName(PyNames.INIT, false, null);
if (init != null) {
return appendToMethod(init, callback);
}
else { // no init! boldly copy ancestor's.
for (PyClass ancestor : cls.getAncestorClasses(null)) {
- init = ancestor.findMethodByName(PyNames.INIT, false);
+ init = ancestor.findMethodByName(PyNames.INIT, false, null);
if (init != null) break;
}
PyFunction newInit = createInitMethod(project, cls, init);
final String complementaryName = PyNames.NEW.equals(functionName) ? PyNames.INIT : PyNames.NEW;
final TypeEvalContext context = TypeEvalContext.userInitiated(project, descriptor.getEndElement().getContainingFile());
final PyFunction complementaryMethod = myOverridenMethod ? (PyFunction)PySuperMethodsSearch.search(function, context).findFirst()
- : cls.findMethodByName(complementaryName, true);
+ : cls.findMethodByName(complementaryName, true, null);
assert complementaryMethod != null;
final PyMethodDescriptor methodDescriptor = new PyMethodDescriptor(function) {
// if we're in a class context and the class defines a variable with the same name, offer auto-import only as quickfix,
// not as popup
PyClass containingClass = PsiTreeUtil.getParentOfType(node, PyClass.class);
- if (containingClass != null && (containingClass.findMethodByName(importFix.getNameToImport(), true) != null ||
+ if (containingClass != null && (containingClass.findMethodByName(importFix.getNameToImport(), true, null) != null ||
containingClass.findInstanceAttribute(importFix.getNameToImport(), true) != null)) {
return true;
}
? PyClassNameIndex.findClass("distutils.command.build_ext.build_ext", file.getProject())
: file.findTopLevelClass(name);
if (taskClass != null) {
- final PyTargetExpression description = taskClass.findClassAttribute("description", true);
+ final PyTargetExpression description = taskClass.findClassAttribute("description", true, null);
if (description != null) {
final String descriptionText = PyPsiUtils.strValue(PyPsiUtils.flattenParens(description.findAssignedValue()));
if (descriptionText != null) {
}
}
- final PyTargetExpression negativeOpt = taskClass.findClassAttribute("negative_opt", true);
+ final PyTargetExpression negativeOpt = taskClass.findClassAttribute("negative_opt", true, null);
final Map<String, String> negativeOptMap = negativeOpt == null
? Collections.<String, String>emptyMap()
: parseNegativeOpt(negativeOpt.findAssignedValue());
private static List<PyExpression> resolveSequenceValue(PyClass aClass, String name) {
List<PyExpression> result = new ArrayList<PyExpression>();
- collectSequenceElements(aClass.findClassAttribute(name, true), result);
+ collectSequenceElements(aClass.findClassAttribute(name, true, null), result);
return result;
}
*/
@Nullable
public static PyFunction getInitMethod(@NotNull final PyClass pyClass) {
- return pyClass.findMethodByName(PyNames.INIT, false);
+ return pyClass.findMethodByName(PyNames.INIT, false, null);
}
/**
return Ref.create(t);
}
if (cls != null && t == null) {
- final PyFunction newMethod = cls.findMethodByName(PyNames.NEW, true);
+ final PyFunction newMethod = cls.findMethodByName(PyNames.NEW, true, null);
if (newMethod != null && !PyBuiltinCache.getInstance(call).isBuiltin(newMethod)) {
return Ref.create(PyUnionType.createWeakType(new PyClassTypeImpl(cls, false)));
}
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
import com.jetbrains.python.documentation.docstrings.DocStringUtil;
import com.jetbrains.python.psi.*;
+import com.jetbrains.python.psi.impl.stubs.PyClassElementType;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.psi.resolve.PyResolveUtil;
import com.jetbrains.python.psi.resolve.QualifiedNameFinder;
}
return PyFileImpl.getStringListFromTargetExpression(PyNames.SLOTS, getClassAttributes());
}
+
@NotNull
public PyClass[] getSuperClasses(@Nullable TypeEvalContext context) {
if (context == null) {
}
}
- public PyFunction findMethodByName(@Nullable final String name, boolean inherited) {
+ @Override
+ public PyFunction findMethodByName(@Nullable final String name, boolean inherited, @Nullable TypeEvalContext context) {
if (name == null) return null;
NameFinder<PyFunction> proc = new NameFinder<PyFunction>(name);
- visitMethods(proc, inherited, null);
+ visitMethods(proc, inherited, context);
return proc.getResult();
}
if (value == null || PyNames.NONE.equals(value)) {
return NONE;
}
- PyFunction method = findMethodByName(value, true);
+ PyFunction method = findMethodByName(value, true, null);
if (method != null) return new Maybe<PyCallable>(method);
}
return UNKNOWN_CALL;
if (property != null) {
return property;
}
- if (findMethodByName(name, false) != null || findClassAttribute(name, false) != null) {
+ if (findMethodByName(name, false, null) != null || findClassAttribute(name, false, null) != null) {
return null;
}
if (inherited) {
return local;
}
if (inherited) {
- if (name != null && (findMethodByName(name, false) != null || findClassAttribute(name, false) != null)) {
+ if (name != null && (findMethodByName(name, false, null) != null || findClassAttribute(name, false, null) != null)) {
return null;
}
for (PyClass cls : getAncestorClasses(null)) {
}
@Override
- public PyTargetExpression findClassAttribute(@NotNull String name, boolean inherited) {
+ public PyTargetExpression findClassAttribute(@NotNull String name, boolean inherited, TypeEvalContext context) {
final NameFinder<PyTargetExpression> processor = new NameFinder<PyTargetExpression>(name);
- visitClassAttributes(processor, inherited, null);
+ visitClassAttributes(processor, inherited, context);
return processor.getResult();
}
Map<String, PyTargetExpression> result = new HashMap<String, PyTargetExpression>();
collectAttributesInNew(result);
- PyFunctionImpl initMethod = (PyFunctionImpl)findMethodByName(PyNames.INIT, false);
+ PyFunctionImpl initMethod = (PyFunctionImpl)findMethodByName(PyNames.INIT, false, null);
if (initMethod != null) {
collectInstanceAttributes(initMethod, result);
}
}
private void collectAttributesInNew(@NotNull final Map<String, PyTargetExpression> result) {
- final PyFunction newMethod = findMethodByName(PyNames.NEW, false);
+ final PyFunction newMethod = findMethodByName(PyNames.NEW, false, null);
if (newMethod != null) {
for (PyTargetExpression target : getTargetExpressions(newMethod)) {
result.put(target.getName(), target);
}
}
}
- if (pyClass.findClassAttribute(PyNames.DUNDER_METACLASS, false) != null) {
+ if (pyClass.findClassAttribute(PyNames.DUNDER_METACLASS, false, null) != null) {
return true;
}
return false;
}
final PyClassStub stub = getStub();
final List<PyClassLikeType> result = new ArrayList<PyClassLikeType>();
+
// In some cases stub may not provide all information, so we use stubs only if AST access id disabled
- if (!context.maySwitchToAST(this) && stub != null) {
- final PsiFile file = getContainingFile();
- if (file instanceof PyFile) {
- for (QualifiedName name : stub.getSuperClasses()) {
- result.add(name != null ? classTypeFromQName(name, (PyFile)file, context) : null);
- }
- }
+ if (!context.maySwitchToAST(this)) {
+ fillSuperClassesNoSwitchToAst(context, stub, result);
}
else {
- for (PyExpression expression : getSuperClassExpressions()) {
- context.getType(expression);
- expression = unfoldClass(expression);
- if (expression instanceof PyKeywordArgument) {
- continue;
- }
- final PyType type = context.getType(expression);
- PyClassLikeType classLikeType = null;
- if (type instanceof PyClassLikeType) {
- classLikeType = (PyClassLikeType)type;
- }
- else {
- final PsiReference ref = expression.getReference();
- if (ref != null) {
- final PsiElement resolved = ref.resolve();
- if (resolved instanceof PyClass) {
- final PyType resolvedType = context.getType((PyClass)resolved);
- if (resolvedType instanceof PyClassLikeType) {
- classLikeType = (PyClassLikeType)resolvedType;
- }
- }
- }
- }
- result.add(classLikeType);
- }
+ fillSuperClassesSwitchingToAst(context, result);
}
+
final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(this);
if (result.isEmpty() && isValid() && !builtinCache.isBuiltin(this)) {
final String implicitSuperName = LanguageLevel.forElement(this).isPy3K() ? PyNames.OBJECT : PyNames.FAKE_OLD_BASE;
return result;
}
+ private void fillSuperClassesSwitchingToAst(@NotNull TypeEvalContext context, List<PyClassLikeType> result) {
+ for (PyExpression expression : getSuperClassExpressions()) {
+ context.getType(expression);
+ expression = unfoldClass(expression);
+ if (expression instanceof PyKeywordArgument) {
+ continue;
+ }
+ final PyType type = context.getType(expression);
+ PyClassLikeType classLikeType = null;
+ if (type instanceof PyClassLikeType) {
+ classLikeType = (PyClassLikeType)type;
+ }
+ else {
+ final PsiReference ref = expression.getReference();
+ if (ref != null) {
+ final PsiElement resolved = ref.resolve();
+ if (resolved instanceof PyClass) {
+ final PyType resolvedType = context.getType((PyClass)resolved);
+ if (resolvedType instanceof PyClassLikeType) {
+ classLikeType = (PyClassLikeType)resolvedType;
+ }
+ }
+ }
+ }
+ result.add(classLikeType);
+ }
+ }
+
+ private void fillSuperClassesNoSwitchToAst(@NotNull final TypeEvalContext context,
+ @Nullable final PyClassStub stub,
+ @NotNull final List<PyClassLikeType> result) {
+ final List<QualifiedName> qualifiedNames;
+ if (stub != null) {
+ qualifiedNames = Arrays.asList(stub.getSuperClasses());
+ }
+ else {
+ qualifiedNames = PyClassElementType.getSuperClassQNames(this);
+ }
+
+
+ final PsiFile file = getContainingFile();
+ if (file instanceof PyFile) {
+ for (QualifiedName name : qualifiedNames) {
+ result.add(name != null ? classTypeFromQName(name, (PyFile)file, context) : null);
+ }
+ }
+ }
+
@NotNull
@Override
public List<PyClassLikeType> getAncestorTypes(@NotNull TypeEvalContext context) {
}
}
else {
- final PyTargetExpression attribute = findClassAttribute(PyNames.DUNDER_METACLASS, false);
+ final PyTargetExpression attribute = findClassAttribute(PyNames.DUNDER_METACLASS, false, null);
if (attribute != null) {
return attribute.findAssignedValue();
}
if (cls == metaClass) {
return false;
}
- final PyFunction mroMethod = metaClass.findMethodByName(PyNames.MRO, true);
+ final PyFunction mroMethod = metaClass.findMethodByName(PyNames.MRO, true, null);
if (mroMethod != null) {
final PyClass mroClass = mroMethod.getContainingClass();
if (mroClass != null && mroClass != typeClass) {
if (indexExpression != null) {
final PyType type = context.getType(getOperand());
final PyClass cls = (type instanceof PyClassType) ? ((PyClassType)type).getPyClass() : null;
- if (cls != null && PyABCUtil.isSubclass(cls, PyNames.MAPPING)) {
+ if (cls != null && PyABCUtil.isSubclass(cls, PyNames.MAPPING, context)) {
return res;
}
if (type instanceof PySubscriptableType) {
final PyType exprType = context.getType(expression);
if (exprType instanceof PyClassType) {
final PyClass cls = ((PyClassType)exprType).getPyClass();
- final PyFunction enter = cls.findMethodByName(PyNames.ENTER, true);
+ final PyFunction enter = cls.findMethodByName(PyNames.ENTER, true, null);
if (enter != null) {
final PyType enterType = enter.getCallType(expression, Collections.<PyExpression, PyNamedParameter>emptyMap(), context);
if (enterType != null) {
addKeywordArgumentVariants((PyCallable)def, callExpr, ret);
}
else if (def instanceof PyClass) {
- PyFunction init = ((PyClass)def).findMethodByName(PyNames.INIT, true); // search in superclasses
+ PyFunction init = ((PyClass)def).findMethodByName(PyNames.INIT, true, null); // search in superclasses
if (init != null) {
addKeywordArgumentVariants(init, callExpr, ret);
}
final PsiElement elt = rrr.getElement();
if (elt instanceof PyClass) {
PyClass cls = (PyClass)elt;
- PyFunction init = cls.findMethodByName(PyNames.INIT, false);
+ PyFunction init = cls.findMethodByName(PyNames.INIT, false, null);
if (init != null) {
// replace
it.set(rrr.replace(init));
}
else { // init not found; maybe it's ancestor's
for (PyClass ancestor : cls.getAncestorClasses(myContext.getTypeEvalContext())) {
- init = ancestor.findMethodByName(PyNames.INIT, false);
+ init = ancestor.findMethodByName(PyNames.INIT, false, null);
if (init != null) {
// add to results as low priority
it.add(new RatedResolveResult(RatedResolveResult.RATE_LOW, init));
}
public PyClassStub createStub(@NotNull final PyClass psi, final StubElement parentStub) {
- final PyExpression[] exprs = psi.getSuperClassExpressions();
+ final List<QualifiedName> superClasses = getSuperClassQNames(psi);
+ final PyStringLiteralExpression docStringExpression = psi.getDocStringExpression();
+ return new PyClassStubImpl(psi.getName(), parentStub,
+ superClasses.toArray(new QualifiedName[superClasses.size()]),
+ PyPsiUtils.asQualifiedName(psi.getMetaClassExpression()),
+ psi.getOwnSlots(),
+ PyPsiUtils.strValue(docStringExpression),
+ getStubElementType());
+ }
+
+ @NotNull
+ public static List<QualifiedName> getSuperClassQNames(@NotNull final PyClass pyClass) {
+ final PyExpression[] exprs = pyClass.getSuperClassExpressions();
List<QualifiedName> superClasses = new ArrayList<QualifiedName>();
for (PyExpression expression : exprs) {
if (expression instanceof PyKeywordArgument) {
expression = PyClassImpl.unfoldClass(expression);
superClasses.add(PyPsiUtils.asQualifiedName(expression));
}
- final PyStringLiteralExpression docStringExpression = psi.getDocStringExpression();
- return new PyClassStubImpl(psi.getName(), parentStub,
- superClasses.toArray(new QualifiedName[superClasses.size()]),
- PyPsiUtils.asQualifiedName(psi.getMetaClassExpression()),
- psi.getOwnSlots(),
- PyPsiUtils.strValue(docStringExpression),
- getStubElementType());
+ return superClasses;
}
public void serialize(@NotNull final PyClassStub pyClassStub, @NotNull final StubOutputStream dataStream) throws IOException {
sink.occurrence(PyClassNameIndexInsensitive.KEY, name.toLowerCase());
}
final PyClass pyClass = createPsi(stub);
- for (String attribute: PyClassAttributesIndex.getAllDeclaredAttributeNames(pyClass)) {
+ for (String attribute : PyClassAttributesIndex.getAllDeclaredAttributeNames(pyClass)) {
sink.occurrence(PyClassAttributesIndex.KEY, attribute);
}
for (QualifiedName s : stub.getSuperClasses()) {
final AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock();
PyFunction overridingMethod;
try {
- overridingMethod = pyClass.findMethodByName(baseMethod.getName(), false);
+ overridingMethod = pyClass.findMethodByName(baseMethod.getName(), false, null);
if (overridingMethod != null) {
final Property baseProperty = baseMethod.getProperty();
final Property overridingProperty = overridingMethod.getProperty();
continue;
}
}
- PyFunction superMethod = superClass.findMethodByName(name, false);
+ PyFunction superMethod = superClass.findMethodByName(name, false, null);
if (superMethod != null) {
final Property property = func.getProperty();
final Property superProperty = superMethod.getProperty();
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.PyClass;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* @author vlan
public static boolean isSubclass(@NotNull PyClass subClass, @NotNull PyClass superClass) {
final String superName = superClass.getName();
if (superName != null) {
- return isSubclass(subClass, superName, true);
+ return isSubclass(subClass, superName, true, null);
}
return false;
}
- public static boolean isSubclass(@NotNull PyClass subClass, @NotNull String superClassName) {
- return isSubclass(subClass, superClassName, true);
+ public static boolean isSubclass(@NotNull PyClass subClass, @NotNull String superClassName, @Nullable TypeEvalContext context) {
+ return isSubclass(subClass, superClassName, true, context);
}
- public static boolean isSubclass(@NotNull PyClass subClass, @NotNull String superClassName, boolean inherited) {
+ public static boolean isSubclass(@NotNull PyClass subClass, @NotNull String superClassName, boolean inherited, @Nullable TypeEvalContext context) {
if (PyNames.CALLABLE.equals(superClassName)) {
- return hasMethod(subClass, PyNames.CALL, inherited);
+ return hasMethod(subClass, PyNames.CALL, inherited, context);
}
if (PyNames.HASHABLE.equals(superClassName)) {
- return hasMethod(subClass, PyNames.HASH, inherited);
+ return hasMethod(subClass, PyNames.HASH, inherited, context);
}
- final boolean hasIter = hasMethod(subClass, PyNames.ITER, inherited);
- final boolean hasGetItem = hasMethod(subClass, PyNames.GETITEM, inherited);
+ final boolean hasIter = hasMethod(subClass, PyNames.ITER, inherited, context);
+ final boolean hasGetItem = hasMethod(subClass, PyNames.GETITEM, inherited, context);
if (PyNames.ITERABLE.equals(superClassName)) {
return hasIter || hasGetItem;
}
if (PyNames.ITERATOR.equals(superClassName)) {
- return (hasIter && (hasMethod(subClass, PyNames.NEXT, inherited) || hasMethod(subClass,
- PyNames.DUNDER_NEXT, inherited))) || hasGetItem;
+ return (hasIter && (hasMethod(subClass, PyNames.NEXT, inherited, context) || hasMethod(subClass,
+ PyNames.DUNDER_NEXT, inherited, context))) || hasGetItem;
}
- final boolean isSized = hasMethod(subClass, PyNames.LEN, inherited);
+ final boolean isSized = hasMethod(subClass, PyNames.LEN, inherited, context);
if (PyNames.SIZED.equals(superClassName)) {
return isSized;
}
- final boolean isContainer = hasMethod(subClass, PyNames.CONTAINS, inherited);
+ final boolean isContainer = hasMethod(subClass, PyNames.CONTAINS, inherited, context);
if (PyNames.CONTAINER.equals(superClassName)) {
return isContainer;
}
return isSized && hasIter && isContainer && hasGetItem;
}
if (PyNames.MAPPING.equals(superClassName)) {
- return isSized && hasIter && isContainer && hasGetItem && hasMethod(subClass, PyNames.KEYS, inherited);
+ return isSized && hasIter && isContainer && hasGetItem && hasMethod(subClass, PyNames.KEYS, inherited, context);
}
if (PyNames.ABC_COMPLEX.equals(superClassName)) {
- return hasMethod(subClass, "__complex__", inherited);
+ return hasMethod(subClass, "__complex__", inherited, context);
}
if (PyNames.ABC_REAL.equals(superClassName)) {
- return hasMethod(subClass, "__float__", inherited);
+ return hasMethod(subClass, "__float__", inherited, context);
}
if (PyNames.ABC_INTEGRAL.equals(superClassName)) {
- return hasMethod(subClass, "__int__", inherited);
+ return hasMethod(subClass, "__int__", inherited, context);
}
if (PyNames.ABC_NUMBER.equals(superClassName) && "Decimal".equals(subClass.getName())) {
return true;
final PyClassLikeType metaClassType = classType.getMetaClassType(context, true);
if (metaClassType instanceof PyClassType) {
final PyClassType metaClass = (PyClassType)metaClassType;
- return isSubclass(metaClass.getPyClass(), superClassName, true);
+ return isSubclass(metaClass.getPyClass(), superClassName, true, null);
}
}
else {
- return isSubclass(pyClass, superClassName, true);
+ return isSubclass(pyClass, superClassName, true, null);
}
}
if (type instanceof PyUnionType) {
return false;
}
- private static boolean hasMethod(PyClass cls, String name, boolean inherited) {
- return cls.findMethodByName(name, inherited) != null || cls.findClassAttribute(name, inherited) != null;
+ private static boolean hasMethod(PyClass cls, String name, boolean inherited, TypeEvalContext context) {
+ return cls.findMethodByName(name, inherited, context) != null || cls.findClassAttribute(name, inherited, context) != null;
}
}
return true;
}
final PyClass cls = getPyClass();
- if (PyABCUtil.isSubclass(cls, PyNames.CALLABLE)) {
+ if (PyABCUtil.isSubclass(cls, PyNames.CALLABLE, null)) {
return true;
}
return false;
if (info instanceof PyChangeInfo && info.isNameChanged()) {
final PyFunction function = ((PyChangeInfo)info).getMethod();
final PyClass clazz = function.getContainingClass();
- if (clazz != null && clazz.findMethodByName(info.getNewName(), true) != null) {
+ if (clazz != null && clazz.findMethodByName(info.getNewName(), true, null) != null) {
conflicts.putValue(function, RefactoringBundle.message("method.0.is.already.defined.in.the.1",
info.getNewName(),
"class " + clazz.getQualifiedName()));
for (final PyFunction method : methods) {
- final PyFunction existingMethod = destination.findMethodByName(method.getName(), false);
+ final PyFunction existingMethod = destination.findMethodByName(method.getName(), false, null);
if ((existingMethod != null) && skipIfExist) {
result.add(existingMethod);
continue; //We skip adding if class already has this method.
@NotNull final PyClass aClass,
@NotNull final String attributeName,
@NotNull final String value) {
- if (aClass.findClassAttribute(attributeName, false) != null) {
+ if (aClass.findClassAttribute(attributeName, false, null) != null) {
return null; //Do not add any if exist already
}
final PyElementGenerator generator = PyElementGenerator.getInstance(aClass.getProject());
@Override
protected boolean classHasField(@NotNull final PyClass pyClass, @NotNull final String fieldName) {
- return pyClass.findClassAttribute(fieldName, true) != null;
+ return pyClass.findClassAttribute(fieldName, true, null) != null;
}
@NotNull
final PyClass clazz = PyUtil.getContainingClassOrSelf(pyFunction);
assert clazz != null : "Refactoring called on function, not method: " + pyFunction;
for (final PyClass parentClass : clazz.getSuperClasses(null)) {
- final PyFunction parentMethod = parentClass.findMethodByName(pyFunction.getName(), true);
+ final PyFunction parentMethod = parentClass.findMethodByName(pyFunction.getName(), true, null);
if (parentMethod != null) {
return true;
}
ScopeOwner owner = parent;
while (owner != null) {
if (owner instanceof PyClass) {
- if (((PyClass)owner).findMethodByName(s, true) != null) {
+ if (((PyClass)owner).findMethodByName(s, true, null) != null) {
return false;
}
}
PyClass clazz = PyUtil.getContainingClassOrSelf(expr);
PsiElement current = PyUtil.getConcealingParent(expression);
if (clazz != null && current != null && current instanceof PyFunction) {
- PyFunction init = clazz.findMethodByName(PyNames.INIT, false);
+ PyFunction init = clazz.findMethodByName(PyNames.INIT, false, null);
if (current == init) {
return true;
}
@Nullable
private static PsiElement addFieldToSetUp(PyClass clazz, final Function<String, PyStatement> callback) {
- final PyFunction init = clazz.findMethodByName(PythonUnitTestUtil.TESTCASE_SETUP_NAME, false);
+ final PyFunction init = clazz.findMethodByName(PythonUnitTestUtil.TESTCASE_SETUP_NAME, false, null);
if (init != null) {
return AddFieldQuickFix.appendToMethod(init, callback);
}
@Override
public Collection<PsiReference> findReferences(final PsiElement element) {
if (element instanceof PyClass) {
- final PyFunction initMethod = ((PyClass)element).findMethodByName(PyNames.INIT, true);
+ final PyFunction initMethod = ((PyClass)element).findMethodByName(PyNames.INIT, true, null);
if (initMethod != null) {
final List<PsiReference> allRefs = Collections.synchronizedList(new ArrayList<PsiReference>());
allRefs.addAll(super.findReferences(element));
if (conflictingClass != null) {
conflicts.putValue(conflictingClass, "A class named '" + newName + "' is already defined in class '" + pyClass.getName() + "'");
}
- PyFunction conflictingFunction = pyClass.findMethodByName(newName, true);
+ PyFunction conflictingFunction = pyClass.findMethodByName(newName, true, null);
if (conflictingFunction != null) {
conflicts.putValue(conflictingFunction, "A function named '" + newName + "' is already defined in class '" + pyClass.getName() + "'");
}
- PyTargetExpression conflictingAttribute = pyClass.findClassAttribute(newName, true);
+ PyTargetExpression conflictingAttribute = pyClass.findClassAttribute(newName, true, null);
if (conflictingAttribute != null) {
conflicts.putValue(conflictingAttribute, "An attribute named '" + newName + "' is already defined in class '" + pyClass.getName() + "'");
}
locations.add(new PsiLocation<PyClass>(project, cls));
}
else {
- final PyFunction method = cls.findMethodByName(methodName, true);
+ final PyFunction method = cls.findMethodByName(methodName, true, null);
if (method == null) {
continue;
}
*/
public void testGetProperty() {
- final PyFunction getter = myClass.findMethodByName("v5getter", false);
+ final PyFunction getter = myClass.findMethodByName("v5getter", false, null);
assertNotNull(getter.getProperty());
- final PyFunction setter = myClass.findMethodByName("v5setter", false);
+ final PyFunction setter = myClass.findMethodByName("v5setter", false, null);
assertNotNull(setter.getProperty());
}
myFixture.configureByFile("override/" + getTestName(true) + ".py");
PyClass dateClass = PyClassNameIndex.findClass("datetime.date", myFixture.getProject());
assertNotNull(dateClass);
- PyFunction initMethod = dateClass.findMethodByName(PyNames.INIT, false);
+ PyFunction initMethod = dateClass.findMethodByName(PyNames.INIT, false, null);
assertNotNull(initMethod);
PyOverrideImplementUtil.overrideMethods(myFixture.getEditor(), getTopLevelClass(0),
Collections.singletonList(new PyMethodMember(initMethod)), false);
public void testInstanceCheck() {
myFixture.configureByFile("override/" + getTestName(true) + ".py");
final PyClass cls = getTopLevelClass(0);
- final PyFunction method = cls.findMethodByName("__instancecheck__", true);
+ final PyFunction method = cls.findMethodByName("__instancecheck__", true, null);
PyOverrideImplementUtil.overrideMethods(myFixture.getEditor(), cls, Collections.singletonList(new PyMethodMember(method)), false);
myFixture.checkResultByFile("override/" + getTestName(true) + "_after.py", true);
}
final PyFile file = getTestFile();
final PyClass c = file.findTopLevelClass("C");
assertNotNull(c);
- final PyTargetExpression foo = c.findClassAttribute("foo", false);
+ final PyTargetExpression foo = c.findClassAttribute("foo", false, null);
final String docString = foo.getDocStringValue();
assertEquals("Foo docstring.", docString);
}
}
public void assertMRO(@NotNull PyClass cls, @NotNull String... mro) {
- final List<PyClassLikeType> types = cls.getAncestorTypes(TypeEvalContext.codeInsightFallback(cls.getProject()));
+ final List<PyClassLikeType> types = cls.getAncestorTypes(TypeEvalContext.deepCodeInsight(cls.getProject()));
final List<String> classNames = new ArrayList<String>();
for (PyClassLikeType type : types) {
if (type != null) {
private PyElement findField(final String className, final String memberName) {
final PyClass aClass = findClass(className);
- final PyTargetExpression attribute = aClass.findClassAttribute(memberName, false);
+ final PyTargetExpression attribute = aClass.findClassAttribute(memberName, false, null);
if (attribute != null) {
return attribute;
}
private PyFunction findMethod(final String className, final String name) {
final PyClass clazz = findClass(className);
- return clazz.findMethodByName(name, false);
+ return clazz.findMethodByName(name, false, null);
}
protected PyClass findClass(final String name) {