PyFunctionBuilder (PyClass pyClass, PyFunction baseFunction, boolean implement) { final String functionName = baseFunction.getName(); final boolean overridingNew = PyNames.NEW.equals(functionName); assert functionName != null; PyFunctionBuilder pyFunctionBuilder = new PyFunctionBuilder(functionName, baseFunction); final PyDecoratorList decorators = baseFunction.getDecoratorList(); boolean baseMethodIsStatic = false; boolean isProperty = false; if (decorators != null) { if (decorators.findDecorator(PyNames.CLASSMETHOD) != null) { pyFunctionBuilder.decorate(PyNames.CLASSMETHOD); } else if (decorators.findDecorator(PyNames.STATICMETHOD) != null) { baseMethodIsStatic = true; pyFunctionBuilder.decorate(PyNames.STATICMETHOD); } else if (decorators.findDecorator(PyNames.PROPERTY) != null || decorators.findDecorator(PyNames.ABSTRACTPROPERTY) != null) { isProperty = true; pyFunctionBuilder.decorate(PyNames.PROPERTY); } } PyAnnotation anno = baseFunction.getAnnotation(); boolean copyAnnotations = PyPsiRefactoringUtil.shouldCopyAnnotations(baseFunction, pyClass.getContainingFile()); if (anno != null && copyAnnotations) { pyFunctionBuilder.annotation(anno.getText()); } if (baseFunction.isAsync()) { pyFunctionBuilder.makeAsync(); } final TypeEvalContext context = TypeEvalContext.userInitiated(baseFunction.getProject(), baseFunction.getContainingFile()); final List<PyCallableParameter> baseParams = baseFunction.getParameters(context); for (PyCallableParameter parameter : baseParams) { final PyParameter psi = parameter.getParameter(); final PyNamedParameter namedParameter = PyUtil.as(psi, PyNamedParameter.class); if (namedParameter != null) { final StringBuilder parameterBuilder = new StringBuilder(); parameterBuilder.append(ParamHelper.getNameInSignature(namedParameter)); final PyAnnotation annotation = namedParameter.getAnnotation(); if (annotation != null && copyAnnotations) { parameterBuilder.append(annotation.getText()); } final PyExpression defaultValue = namedParameter.getDefaultValue(); if (defaultValue != null) { parameterBuilder.append("="); parameterBuilder.append(defaultValue.getText()); } pyFunctionBuilder.parameter(parameterBuilder.toString()); } else if (psi != null) { pyFunctionBuilder.parameter(psi.getText()); } } PyClass baseClass = baseFunction.getContainingClass(); assert baseClass != null; StringBuilder statementBody = new StringBuilder(); boolean hadStar = false; List<String> parameters = new ArrayList<>(); for (PyCallableParameter parameter : baseParams) { final PyParameter psi = parameter.getParameter(); final PyNamedParameter namedParameter = PyUtil.as(psi, PyNamedParameter.class); if (namedParameter != null) { final String repr = namedParameter.getRepr(false); parameters.add(hadStar && !namedParameter.isKeywordContainer() ? namedParameter.getName() + "=" + repr : repr); if (namedParameter.isPositionalContainer()) { hadStar = true; } } else if (psi instanceof PySingleStarParameter) { hadStar = true; } else if (psi != null && !(psi instanceof PySlashParameter)) { parameters.add(psi.getText()); } } if (implement || baseFunction.onlyRaisesNotImplementedError() || PyKnownDecoratorUtil.hasAbstractDecorator(baseFunction, context)) { statementBody.append(PyNames.PASS); } else { if (!PyNames.INIT.equals(functionName) && context.getReturnType(baseFunction) != PyNoneType.INSTANCE || overridingNew || isProperty) { statementBody.append("return "); } if (baseFunction.isAsync()) { statementBody.append(PyNames.AWAIT); statementBody.append(" "); } if (baseClass.isNewStyleClass(context)) { statementBody.append(PyNames.SUPER); statementBody.append("("); final LanguageLevel langLevel = ((PyFile)pyClass.getContainingFile()).getLanguageLevel(); if (langLevel.isPython2()) { final String baseFirstName = !baseParams.isEmpty() ? baseParams.get(0).getName() : null; final String firstName = baseFirstName != null ? baseFirstName : PyNames.CANONICAL_SELF; PyClass outerClass = PsiTreeUtil.getParentOfType(pyClass, PyClass.class, true, PyFunction.class); String className = pyClass.getName(); final List<String> nameResult = Lists.newArrayList(className); while (outerClass != null) { nameResult.add(0, outerClass.getName()); outerClass = PsiTreeUtil.getParentOfType(outerClass, PyClass.class, true, PyFunction.class); } StringUtil.join(nameResult, ".", statementBody); statementBody.append(", ").append(firstName); } statementBody.append(").").append(functionName); if (parameters.size() > 0 && !(baseMethodIsStatic || overridingNew)) { parameters.remove(0); } } else { statementBody.append(getReferenceText(pyClass, baseClass)).append(".").append(functionName); } if (!isProperty) { statementBody.append("("); StringUtil.join(parameters, ", ", statementBody); statementBody.append(")"); } } pyFunctionBuilder.statement(statementBody.toString()); return pyFunctionBuilder; }