import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ArrayUtil;
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
-import com.jetbrains.python.documentation.docstrings.DocStringUpdater;
-import com.jetbrains.python.documentation.docstrings.GoogleCodeStyleDocStringUpdater;
-import com.jetbrains.python.documentation.docstrings.NumpyDocStringUpdater;
-import com.jetbrains.python.documentation.docstrings.TagBasedDocStringUpdater;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyPsiUtils;
import com.jetbrains.python.psi.impl.PyStringLiteralExpressionImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.Arrays;
-import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
final PyDocumentationSettings settings = PyDocumentationSettings.getInstance(getModuleForElement(anchor));
return settings.getFormatForFile(anchor.getContainingFile());
}
-
- public static PyStringLiteralExpression removeParamsFromDocString(@NotNull PyStringLiteralExpression docString,
- @NotNull Collection<String> paramNames) {
- final Module module = getModuleForElement(docString);
- final DocStringFormat format = PyDocumentationSettings.getInstance(module).getFormatForFile(docString.getContainingFile());
- DocStringUpdater updater;
- switch (format) {
- case EPYTEXT:
- final EpydocString epyParsed = (EpydocString)parseDocString(format, docString);
- updater = new TagBasedDocStringUpdater(epyParsed, "@", PyIndentUtil.getElementIndent(docString));
- break;
- case REST:
- final SphinxDocString restParsed = (SphinxDocString)parseDocString(format, docString);
- updater = new TagBasedDocStringUpdater(restParsed, ":", PyIndentUtil.getElementIndent(docString));
- break;
- case GOOGLE:
- final GoogleCodeStyleDocString googleParsed = (GoogleCodeStyleDocString)parseDocString(format, docString);
- updater = new GoogleCodeStyleDocStringUpdater(googleParsed, PyIndentUtil.getElementIndent(docString));
- break;
- case NUMPY:
- final NumpyDocString numpyParsed = (NumpyDocString)parseDocString(format, docString);
- updater = new NumpyDocStringUpdater(numpyParsed, PyIndentUtil.getElementIndent(docString));
- break;
- default:
- return docString;
- }
- for (String name : paramNames) {
- updater.removeParameter(name);
- }
- final String newText = updater.getDocStringText();
- final PyExpressionStatement replacement = PyElementGenerator.getInstance(docString.getProject()).createDocstring(newText);
- return (PyStringLiteralExpression)docString.replace(replacement.getExpression());
-
- }
-
- @NotNull
- public static PyStringLiteralExpression removeParamsFromDocString(@NotNull PyStringLiteralExpression docString,
- @NotNull String... paramNames) {
- return removeParamsFromDocString(docString, Arrays.asList(paramNames));
- }
}
*/
public class PyDocstringGenerator {
- private final List<DocstringParam> myParams = Lists.newArrayList();
+ private final List<DocstringParam> myAddedParams = Lists.newArrayList();
+ private final List<DocstringParam> myRemovedParams = Lists.newArrayList();
// Updated after buildAndInsert
@NotNull
private PyDocStringOwner myDocStringOwner;
return withParamTypedByName(name, null);
}
+ @NotNull
+ public PyDocstringGenerator withoutParam(@NotNull String name) {
+ myRemovedParams.add(new DocstringParam(name, null, false));
+ return this;
+ }
+
@NotNull
public PyDocstringGenerator withParamTypedByName(@NotNull String name, @Nullable String type) {
- myParams.add(new DocstringParam(name, type, false));
+ myAddedParams.add(new DocstringParam(name, type, false));
return this;
}
@NotNull
public PyDocstringGenerator withReturnValue(@Nullable String type) {
- myParams.add(new DocstringParam("", type, true));
+ myAddedParams.add(new DocstringParam("", type, true));
return this;
}
}
private void prepareParameters() {
- // Populate parameter list, if no one was specified explicitly
- if (!myParametersPrepared && myParams.isEmpty()) {
+ // Populate parameter list, if no one was specified explicitly to add or remove
+ if (!myParametersPrepared && myAddedParams.isEmpty() && myRemovedParams.isEmpty()) {
if (myDocStringOwner instanceof PyFunction) {
PySignature signature = null;
if (myUseTypesFromDebuggerSignature) {
statementList.accept(visitor);
if (visitor.myHasReturn || myAlwaysGenerateReturn) {
// will add :return: placeholder in Sphinx/Epydoc docstrings
- myParams.add(new DocstringParam("", null, true));
+ myAddedParams.add(new DocstringParam("", null, true));
if (PyCodeInsightSettings.getInstance().INSERT_TYPE_DOCSTUB) {
withReturnValue("");
}
if (format == DocStringFormat.GOOGLE || format == DocStringFormat.NUMPY) {
// Google and Numpy docstring formats combine type and description in single declaration, thus
// if both declaration with type and without it are requested, we should filter out duplicates
- final ArrayList<DocstringParam> copy = new ArrayList<DocstringParam>(myParams);
+ final ArrayList<DocstringParam> copy = new ArrayList<DocstringParam>(myAddedParams);
for (final DocstringParam param : copy) {
if (param.getType() == null) {
- final DocstringParam sameParamWithType = ContainerUtil.find(myParams, new Condition<DocstringParam>() {
+ final DocstringParam sameParamWithType = ContainerUtil.find(myAddedParams, new Condition<DocstringParam>() {
@Override
public boolean value(DocstringParam other) {
return other.isReturnValue() == param.isReturnValue() && other.getName().equals(param.getName()) && other.getType() != null;
}
});
if (sameParamWithType != null) {
- myParams.remove(param);
+ myAddedParams.remove(param);
}
}
}
public boolean hasParametersToAdd() {
prepareParameters();
- return !myParams.isEmpty();
+ return !myAddedParams.isEmpty();
}
@Nullable
final TemplateBuilder builder = TemplateBuilderFactory.getInstance().createTemplateBuilder(docStringExpression);
- if (myParams.size() > 1) {
+ if (myAddedParams.size() > 1) {
throw new IllegalArgumentException("TemplateBuilder can be created only for one parameter");
}
}
}
+ @NotNull
+ private String getDocStringIndentation() {
+ String indentation = "";
+ if (myDocStringOwner instanceof PyStatementListContainer) {
+ indentation = PyIndentUtil.getElementIndent(((PyStatementListContainer)myDocStringOwner).getStatementList());
+ }
+ return indentation;
+ }
+
@NotNull
public String buildDocString() {
prepareParameters();
if (myAddFirstEmptyLine) {
tagBuilder.addEmptyLine();
}
- for (DocstringParam param : myParams) {
+ for (DocstringParam param : myAddedParams) {
if (param.isReturnValue()) {
if (param.getType() != null) {
tagBuilder.addReturnValueType(param.getType());
if (myAddFirstEmptyLine) {
sectionBuilder.addEmptyLine();
}
- final List<DocstringParam> parameters = ContainerUtil.findAll(myParams, new Condition<DocstringParam>() {
+ final List<DocstringParam> parameters = ContainerUtil.findAll(myAddedParams, new Condition<DocstringParam>() {
@Override
public boolean value(DocstringParam param) {
return !param.isReturnValue();
}
}
- final List<DocstringParam> returnValues = ContainerUtil.findAll(myParams, new Condition<DocstringParam>() {
+ final List<DocstringParam> returnValues = ContainerUtil.findAll(myAddedParams, new Condition<DocstringParam>() {
@Override
public boolean value(DocstringParam param) {
return param.isReturnValue();
return myQuotes + '\n' + indentation + myQuotes;
}
- @NotNull
- private String getDocStringIndentation() {
- String indentation = "";
- if (myDocStringOwner instanceof PyStatementListContainer) {
- indentation = PyIndentUtil.getElementIndent(((PyStatementListContainer)myDocStringOwner).getStatementList());
- }
- return indentation;
- }
-
@NotNull
private String updateDocString() {
final DocStringFormat format = getDocStringFormat();
updater = new NumpyDocStringUpdater((SectionBasedDocString)getStructuredDocString(), docStringIndent);
}
if (updater != null) {
- for (DocstringParam param : myParams) {
+ for (DocstringParam param : myAddedParams) {
if (param.isReturnValue()) {
updater.addReturnValue(param.getType());
}
updater.addParameter(param.getName(), param.getType());
}
}
+ for (DocstringParam param : myRemovedParams) {
+ if (!param.isReturnValue()) {
+ updater.removeParameter(param.getName());
+ }
+ }
return updater.getDocStringText();
}
return myQuotes + myQuotes;
}
private DocstringParam getParamToEdit() {
- if (myParams.size() == 0) {
+ if (myAddedParams.size() == 0) {
throw new IllegalStateException("We should have at least one param to edit");
}
- return myParams.get(0);
+ return myAddedParams.get(0);
}
@NotNull