/** * Looks for two standard decorators to a function, or a wrapping assignment that closely follows * it. * * @return a flag describing what was detected. */ @Nullable public Modifier getModifier() { final String deconame = getClassOrStaticMethodDecorator(); if (PyNames.CLASSMETHOD.equals(deconame)) { return CLASSMETHOD; } else if (PyNames.STATICMETHOD.equals(deconame)) { return STATICMETHOD; } // implicit staticmethod __new__ final PyClass cls = getContainingClass(); if (cls != null && PyNames.NEW.equals(getName()) && cls.isNewStyleClass(null)) { return STATICMETHOD; } // if (getStub() != null) { return getWrappersFromStub(); } final String funcName = getName(); if (funcName != null) { PyAssignmentStatement currentAssignment = PsiTreeUtil.getNextSiblingOfType(this, PyAssignmentStatement.class); while (currentAssignment != null) { final String modifier = currentAssignment .getTargetsToValuesMapping() .stream() .filter( pair -> pair.getFirst() instanceof PyTargetExpression && funcName.equals(pair.getFirst().getName())) .filter(pair -> pair.getSecond() instanceof PyCallExpression) .map( pair -> interpretAsModifierWrappingCall((PyCallExpression) pair.getSecond(), this)) .filter(interpreted -> interpreted != null && interpreted.getSecond() == this) .map(interpreted -> interpreted.getFirst()) .filter( wrapperName -> PyNames.CLASSMETHOD.equals(wrapperName) || PyNames.STATICMETHOD.equals(wrapperName)) .findAny() .orElse(null); if (PyNames.CLASSMETHOD.equals(modifier)) { return CLASSMETHOD; } else if (PyNames.STATICMETHOD.equals(modifier)) { return STATICMETHOD; } currentAssignment = PsiTreeUtil.getNextSiblingOfType(currentAssignment, PyAssignmentStatement.class); } } return null; }
/** * Looks for two standard decorators to a function, or a wrapping assignment that closely follows * it. * * @return a flag describing what was detected. */ @Nullable public Modifier getModifier() { String deconame = getClassOrStaticMethodDecorator(); if (PyNames.CLASSMETHOD.equals(deconame)) { return CLASSMETHOD; } else if (PyNames.STATICMETHOD.equals(deconame)) { return STATICMETHOD; } // implicit staticmethod __new__ PyClass cls = getContainingClass(); if (cls != null && PyNames.NEW.equals(getName()) && cls.isNewStyleClass(null)) { return STATICMETHOD; } // if (getStub() != null) { return getWrappersFromStub(); } String func_name = getName(); if (func_name != null) { PyAssignmentStatement assignment = PsiTreeUtil.getNextSiblingOfType(this, PyAssignmentStatement.class); if (assignment != null) { for (Pair<PyExpression, PyExpression> pair : assignment.getTargetsToValuesMapping()) { PyExpression value = pair.getSecond(); if (value instanceof PyCallExpression) { PyExpression target = pair.getFirst(); if (target instanceof PyTargetExpression && func_name.equals(target.getName())) { Pair<String, PyFunction> interpreted = interpretAsModifierWrappingCall((PyCallExpression) value, this); if (interpreted != null) { PyFunction original = interpreted.getSecond(); if (original == this) { String wrapper_name = interpreted.getFirst(); if (PyNames.CLASSMETHOD.equals(wrapper_name)) { return CLASSMETHOD; } else if (PyNames.STATICMETHOD.equals(wrapper_name)) { return STATICMETHOD; } } } } } } } } return null; }
/** @param self should be this */ @NotNull private static List<PyAssignmentStatement> findAttributesStatic(@NotNull final PsiElement self) { final List<PyAssignmentStatement> result = new ArrayList<>(); for (final PyAssignmentStatement statement : new PsiQuery(self).siblings(PyAssignmentStatement.class).getElements()) { for (final PyQualifiedExpression targetExpression : new PsiQuery(statement.getTargets()).filter(PyQualifiedExpression.class).getElements()) { final PyExpression qualifier = targetExpression.getQualifier(); if (qualifier == null) { continue; } final PsiReference qualifierReference = qualifier.getReference(); if (qualifierReference == null) { continue; } if (qualifierReference.isReferenceTo(self)) { result.add(statement); } } } return result; }