mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-13 09:19:13 +07:00
PY-16870 Complete parameter in Google docstring when there is no colon after them yet
This commit is contained in:
+1
@@ -58,6 +58,7 @@ public class PyDocstringCompletionContributor extends CompletionContributor {
|
||||
final PsiElement element = parameters.getOriginalPosition();
|
||||
if (element == null) return;
|
||||
final PsiFile file = element.getContainingFile();
|
||||
// Parameter references are filled with DocStringParameterReference#getVariants
|
||||
if (file.findReferenceAt(parameters.getOffset()) != null) return;
|
||||
final PyDocStringOwner docStringOwner = PsiTreeUtil.getParentOfType(element, PyDocStringOwner.class);
|
||||
final Module module = ModuleUtilCore.findModuleForPsiElement(element);
|
||||
|
||||
+1
-4
@@ -19,10 +19,8 @@ import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.PsiReferenceProvider;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.psi.PyDocStringOwner;
|
||||
import com.jetbrains.python.psi.PyImportElement;
|
||||
import com.jetbrains.python.psi.PyStringLiteralExpression;
|
||||
import com.jetbrains.python.psi.StructuredDocString;
|
||||
@@ -44,8 +42,7 @@ public class DocStringReferenceProvider extends PsiReferenceProvider {
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiReference[] getReferencesByElement(@NotNull final PsiElement element, @NotNull ProcessingContext context) {
|
||||
final PyDocStringOwner docStringOwner = PsiTreeUtil.getParentOfType(element, PyDocStringOwner.class);
|
||||
if (docStringOwner != null && element == docStringOwner.getDocStringExpression()) {
|
||||
if (element == DocStringUtil.getParentDefinitionDocString(element)) {
|
||||
final PyStringLiteralExpression expr = (PyStringLiteralExpression)element;
|
||||
final List<TextRange> ranges = expr.getStringValueTextRanges();
|
||||
|
||||
|
||||
+3
@@ -42,6 +42,9 @@ public class DocStringSectionHeaderCompletionContributor extends CompletionContr
|
||||
final PsiElement stringNode = parameters.getOriginalPosition();
|
||||
assert stringNode != null;
|
||||
final int offset = parameters.getOffset();
|
||||
if (file.findReferenceAt(offset) != null) {
|
||||
return;
|
||||
}
|
||||
final DocStringFormat format = DocStringUtil.getConfiguredDocStringFormat(file);
|
||||
if (!(format == DocStringFormat.GOOGLE || format == DocStringFormat.NUMPY)) {
|
||||
return;
|
||||
|
||||
+16
-13
@@ -78,12 +78,11 @@ public class GoogleCodeStyleDocString extends SectionBasedDocString {
|
||||
boolean mayHaveType,
|
||||
boolean preferType) {
|
||||
final Substring line = getLine(lineNum);
|
||||
Substring name, type = null, description;
|
||||
Substring name, type = null;
|
||||
// Napoleon requires that each parameter line contains a colon - we don't because
|
||||
// we need to parse and complete parameter names before colon is typed
|
||||
final List<Substring> colonSeparatedParts = splitByFirstColon(line);
|
||||
assert colonSeparatedParts.size() <= 2;
|
||||
if (colonSeparatedParts.size() < 2) {
|
||||
return Pair.create(null, lineNum);
|
||||
}
|
||||
final Substring textBeforeColon = colonSeparatedParts.get(0);
|
||||
name = textBeforeColon.trim();
|
||||
if (mayHaveType) {
|
||||
@@ -104,16 +103,20 @@ public class GoogleCodeStyleDocString extends SectionBasedDocString {
|
||||
if (name != null ? !PyNames.isIdentifierString(name.toString()) : type.isEmpty()) {
|
||||
return Pair.create(null, lineNum);
|
||||
}
|
||||
description = colonSeparatedParts.get(1);
|
||||
// parse line with indentation at least one space greater than indentation of the field
|
||||
final Pair<List<Substring>, Integer> pair = parseIndentedBlock(lineNum + 1, getLineIndentSize(lineNum));
|
||||
final List<Substring> nestedBlock = pair.getFirst();
|
||||
if (!nestedBlock.isEmpty()) {
|
||||
//noinspection ConstantConditions
|
||||
description = description.union(ContainerUtil.getLastItem(nestedBlock));
|
||||
final Pair<List<Substring>, Integer> pair;
|
||||
if (colonSeparatedParts.size() == 2) {
|
||||
Substring description = colonSeparatedParts.get(1);
|
||||
// parse line with indentation at least one space greater than indentation of the field
|
||||
pair = parseIndentedBlock(lineNum + 1, getLineIndentSize(lineNum));
|
||||
final List<Substring> nestedBlock = pair.getFirst();
|
||||
if (!nestedBlock.isEmpty()) {
|
||||
//noinspection ConstantConditions
|
||||
description = description.union(ContainerUtil.getLastItem(nestedBlock));
|
||||
}
|
||||
description = description.trim();
|
||||
return Pair.create(new SectionField(name, type, description), pair.getSecond());
|
||||
}
|
||||
description = description.trim();
|
||||
return Pair.create(new SectionField(name, type, description), pair.getSecond());
|
||||
return Pair.create(new SectionField(name, type, null), lineNum + 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
def f(param1, param2):
|
||||
"""
|
||||
Args:
|
||||
par<caret>
|
||||
"""
|
||||
@@ -0,0 +1,5 @@
|
||||
def f(param1, param2):
|
||||
"""
|
||||
Args:
|
||||
par<caret>
|
||||
"""
|
||||
@@ -0,0 +1,6 @@
|
||||
def f(x, y):
|
||||
"""
|
||||
Args:
|
||||
x
|
||||
y (int)
|
||||
"""
|
||||
@@ -1,7 +1,7 @@
|
||||
def f():
|
||||
"""
|
||||
Returns:
|
||||
object:
|
||||
object:
|
||||
|
||||
Raises:
|
||||
RuntimeException
|
||||
|
||||
@@ -2,7 +2,7 @@ def f(x):
|
||||
"""
|
||||
|
||||
Args:
|
||||
x:
|
||||
x:
|
||||
|
||||
Keyword arguments:
|
||||
|
||||
|
||||
@@ -328,6 +328,22 @@ public class PySectionBasedDocStringTest extends PyTestCase {
|
||||
assertEquals("args", paramSection.getFields().get(1).getName());
|
||||
}
|
||||
|
||||
public void testGoogleNoColonAfterParameter() {
|
||||
final GoogleCodeStyleDocString docString = findAndParseGoogleStyleDocString();
|
||||
assertSize(1, docString.getSections());
|
||||
final Section paramSection = docString.getSections().get(0);
|
||||
assertSize(2, paramSection.getFields());
|
||||
final SectionField x = paramSection.getFields().get(0);
|
||||
assertEquals("x", x.getName());
|
||||
assertEmpty(x.getType());
|
||||
assertEmpty(x.getDescription());
|
||||
|
||||
final SectionField y = paramSection.getFields().get(1);
|
||||
assertEquals("y", y.getName());
|
||||
assertEquals("int", y.getType());
|
||||
assertEmpty(y.getDescription());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return super.getTestDataPath() + "/docstrings";
|
||||
|
||||
@@ -426,6 +426,18 @@ public class PythonCompletionTest extends PyTestCase {
|
||||
});
|
||||
}
|
||||
|
||||
// PY-16870
|
||||
public void testParamNameInGoogleDocstring() {
|
||||
runWithDocStringFormat(DocStringFormat.GOOGLE, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final List<String> variants = doTestByFile();
|
||||
assertNotNull(variants);
|
||||
assertSameElements(variants, "param1", "param2");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testPep328Completion() { // PY-3409
|
||||
myFixture.copyDirectoryToProject("pep328", "pep328");
|
||||
myFixture.configureByFile("pep328/package/subpackage1/moduleX.py");
|
||||
|
||||
Reference in New Issue
Block a user