PsiElement (@NotNull PsiElement elementDefinition, @Nullable PsiElement outerElement) { if (myOriginalElement == null) { return null; } final String propertyName = myOriginalElement.getText(); if (!PyNames.isIdentifier(propertyName)) { return null; } if (!(outerElement instanceof PyQualifiedExpression)) { return null; } final PyExpression qualifier = ((PyQualifiedExpression)outerElement).getQualifier(); if (qualifier == null) { return null; } final PyType type = myContext.getType(qualifier); if (!(type instanceof PyClassType)) { return null; } final PyClass cls = ((PyClassType)type).getPyClass(); final Property property = cls.findProperty(propertyName, true, null); if (property == null) { return null; } final AccessDirection direction = AccessDirection.of((PyElement)outerElement); final Maybe<PyCallable> accessor = property.getByDirection(direction); final HtmlChunk link = getLinkToClass(cls, true); if (link != null) { myBody.appendRaw(PyPsiBundle.message("QDOC.property.name.of.link", HtmlChunk.text(propertyName).bold(), link)).br(); } // Choose appropriate docstring String docstring = null; if (property.getDoc() != null) { docstring = property.getDoc(); } if (docstring == null) { final PyFunction accessorFunc = as(accessor.valueOrNull(), PyFunction.class); if (accessorFunc != null) { final PyStringLiteralExpression accessorDocstring = getEffectiveDocStringExpression(accessorFunc); if (accessorDocstring != null) { docstring = accessorDocstring.getStringValue(); } } } final Maybe<PyCallable> propertyGetter = property.getGetter(); if (docstring == null && direction != AccessDirection.READ) { final PyFunction getter = as(propertyGetter.valueOrNull(), PyFunction.class); if (getter != null) { // not in getter, getter's doc comment may be useful final PyStringLiteralExpression getterDocstring = getEffectiveDocStringExpression(getter); if (getterDocstring != null) { mySectionsMap.get(PyPsiBundle.message("QDOC.copied.from")).append(PyPsiBundle.message("QDOC.property.getter")); docstring = getterDocstring.getStringValue(); } } } if (docstring != null) { myContent.append(safeRunFormatterService(elementDefinition, docstring)); } mySectionsMap.get(PyPsiBundle.message("QDOC.accessor.kind")).append(getAccessorKind(direction)) .append(accessor.valueOrNull() == null ? " " + PyPsiBundle.message("QDOC.not.defined.in.parentheses") : ""); // Choose appropriate definition to display if (accessor.valueOrNull() != null) { return accessor.value(); } else if (propertyGetter.valueOrNull() != null) { return propertyGetter.value(); } else { return property.getDefinitionSite(); } }