@Override
    public void visitPyReferenceExpression(PyReferenceExpression node) {
      final PyExpression qualifier = node.getQualifier();
      if (qualifier == null || PyNames.CANONICAL_SELF.equals(qualifier.getText())) return;
      if (myTypeEvalContext.getType(qualifier) instanceof PyNamedTupleType) return;
      final String name = node.getName();
      final List<LocalQuickFix> quickFixes = new ArrayList<LocalQuickFix>();
      quickFixes.add(new PyRenameElementQuickFix());

      if (name != null && name.startsWith("_") && !name.startsWith("__") && !name.endsWith("__")) {
        final PsiReference reference = node.getReference(getResolveContext());
        if (reference == null) return;
        final PsiElement resolvedExpression = reference.resolve();
        final PyClass resolvedClass = getClassOwner(resolvedExpression);
        if (resolvedExpression instanceof PyTargetExpression) {
          final String newName = StringUtil.trimLeading(name, '_');
          if (resolvedClass != null) {
            final String qFixName =
                resolvedClass.getProperties().containsKey(newName)
                    ? PyBundle.message("QFIX.use.property")
                    : PyBundle.message("QFIX.add.property");
            quickFixes.add(new PyAddPropertyForFieldQuickFix(qFixName));

            final Collection<String> usedNames = PyRefactoringUtil.collectUsedNames(resolvedClass);
            if (!usedNames.contains(newName)) {
              quickFixes.add(new PyMakePublicQuickFix());
            }
          }
        }

        final PyClass parentClass = getClassOwner(node);
        if (parentClass != null) {
          if (PyTestUtil.isPyTestClass(parentClass) && ignoreTestFunctions) return;

          if (parentClass.isSubclass(resolvedClass)) return;

          PyClass outerClass = getClassOwner(parentClass);
          while (outerClass != null) {
            if (outerClass.isSubclass(resolvedClass)) return;

            outerClass = getClassOwner(outerClass);
          }
        }
        final PyType type = myTypeEvalContext.getType(qualifier);
        final String bundleKey =
            type instanceof PyModuleType
                ? "INSP.protected.member.$0.access.module"
                : "INSP.protected.member.$0.access";
        registerProblem(
            node,
            PyBundle.message(bundleKey, name),
            ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
            null,
            quickFixes.toArray(new LocalQuickFix[quickFixes.size() - 1]));
      }
    }
 public PyStatement fun(String self_name) {
   if (PyNames.CANONICAL_SELF.equals(self_name)) {
     return (PyStatement) myDeclaration;
   }
   final String text = myDeclaration.getText();
   final Project project = myDeclaration.getProject();
   return PyElementGenerator.getInstance(project)
       .createFromText(
           LanguageLevel.getDefault(),
           PyStatement.class,
           text.replaceFirst(PyNames.CANONICAL_SELF + "\\.", self_name + "."));
 }