void (final @NotNull PyFunction node) { for (PyInspectionExtension extension : PyInspectionExtension.EP_NAME.getExtensionList()) { if (extension.ignoreMethodParameters(node, myTypeEvalContext)) { return; } } // analyze function itself PyUtil.MethodFlags flags = PyUtil.MethodFlags.of(node); if (flags != null) { PyParameterList plist = node.getParameterList(); PyParameter[] params = plist.getParameters(); final String methodName = node.getName(); if (params.length == 0) { // fix: add // check for "staticmetod" if (flags.isStaticMethod()) return; // no params may be fine // check actual param list ASTNode name_node = node.getNameNode(); if (name_node != null) { PsiElement open_paren = plist.getFirstChild(); PsiElement close_paren = plist.getLastChild(); if ( open_paren != null && close_paren != null && "(".equals(open_paren.getText()) && ")".equals(close_paren.getText()) ) { String paramName; if (flags.isMetaclassMethod() || flags.isClassMethod()) { paramName = PyNames.CANONICAL_CLS; } else { paramName = PyNames.CANONICAL_SELF; } registerProblem( plist, PyPsiBundle.message("INSP.must.have.first.parameter", paramName), ProblemHighlightType.GENERIC_ERROR, null, new AddSelfQuickFix(paramName) ); } } } else { // fix: rename PyNamedParameter first_param = params[0].getAsNamed(); if (first_param != null) { String pname = first_param.getName(); if (pname == null) { return; } // every dup, swap, drop, or dup+drop of "self" @NonNls String[] mangled = {"eslf", "sself", "elf", "felf", "slef", "seelf", "slf", "sslf", "sefl", "sellf", "sef", "seef"}; if (PyUtil.among(pname, mangled)) { registerProblem( PyUtil.sure(params[0].getNode()).getPsi(), PyPsiBundle.message("INSP.probably.mistyped.self"), new RenameParameterQuickFix(PyNames.CANONICAL_SELF) ); return; } if (flags.isMetaclassMethod()) { if (flags.isStaticMethod() && !PyNames.NEW.equals(methodName)) { return; } String expectedName; Set<String> alternativeNames; if (PyNames.NEW.equals(methodName) || flags.isClassMethod()) { expectedName = PyNames.CANONICAL_CLS; alternativeNames = Set.of("mcs", "mcls", "metacls"); } else if (flags.isSpecialMetaclassMethod()) { expectedName = PyNames.CANONICAL_CLS; alternativeNames = Set.of(); } else { expectedName = PyNames.CANONICAL_SELF; alternativeNames = Set.of(PyNames.CANONICAL_CLS); } if (!expectedName.equals(pname) && !alternativeNames.contains(pname)) { registerProblem( PyUtil.sure(params[0].getNode()).getPsi(), PyPsiBundle.message("INSP.usually.named", expectedName), new RenameParameterQuickFix(expectedName) ); } } else if (flags.isClassMethod() || PyNames.NEW.equals(methodName)) { if (!PyNames.CANONICAL_CLS.equals(pname)) { registerProblem( PyUtil.sure(params[0].getNode()).getPsi(), PyPsiBundle.message("INSP.usually.named", PyNames.CANONICAL_CLS), new RenameParameterQuickFix(PyNames.CANONICAL_CLS) ); } } else if (!flags.isStaticMethod() && !first_param.isPositionalContainer() && !PyNames.CANONICAL_SELF.equals(pname)) { registerProblem( PyUtil.sure(params[0].getNode()).getPsi(), PyPsiBundle.message("INSP.usually.named.self"), new RenameParameterQuickFix(PyNames.CANONICAL_SELF) ); } } else { // the unusual case of a method with first tuple param if (!flags.isStaticMethod()) { registerProblem(plist, PyPsiBundle.message("INSP.first.param.must.not.be.tuple")); } } } } }