PY-9795 Handle colons in Shpinx references inside docstring as Napoleon does

This commit is contained in:
Mikhail Golubev
2015-09-02 14:34:00 +03:00
parent 6b87c7c1f8
commit a096eb159d
3 changed files with 60 additions and 11 deletions
@@ -20,6 +20,8 @@ import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.python.toolbox.Substring;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -73,7 +75,6 @@ public class GoogleCodeStyleDocString extends SectionBasedDocString {
type = textBeforeColon.trim();
}
else {
// TODO skip references in types like Napoleon does
final Matcher matcher = FIELD_NAME_AND_TYPE_RE.matcher(textBeforeColon);
if (matcher.matches()) {
name = Substring.fromMatcherGroup(textBeforeColon, matcher, 1).trim();
@@ -103,7 +104,19 @@ public class GoogleCodeStyleDocString extends SectionBasedDocString {
* </code></pre>
*/
@NotNull
private List<Substring> splitFieldStartLineByColon(@NotNull Substring line) {
private static List<Substring> splitFieldStartLineByColon(@NotNull Substring line) {
final List<Substring> parts = line.split(SPHINX_REFERENCE_RE);
if (parts.size() > 1) {
for (Substring part : parts) {
final int i = part.indexOf(":");
if (i >= 0){
final Substring beforeColon = new Substring(line.getSuperString(), line.getStartOffset(), part.getStartOffset() + i);
final Substring afterColon = new Substring(line.getSuperString(), part.getStartOffset() + i + 1, line.getEndOffset());
return Arrays.asList(beforeColon, afterColon);
}
}
return Collections.singletonList(line);
}
return line.split(":", 1);
}
@@ -0,0 +1,8 @@
def func(a1):
"""
Parameters:
a1 (:class:`MyClass`): used to call :def:`my_function` and access :attr:`my_attr`
Raises:
:class:`MyException`: thrown in case of any error
"""
@@ -34,11 +34,7 @@ import java.util.List;
public class PyGoogleCodeStyleDocStringTest extends PyTestCase {
public void testSimpleFunctionDocString() {
myFixture.configureByFile(getTestName(true) + ".py");
final String docStringText = findFirstDocString();
assertNotNull(docStringText);
final GoogleCodeStyleDocString docString = new GoogleCodeStyleDocString(docStringText);
final GoogleCodeStyleDocString docString = findAndParseDocString();
assertEquals("Summary", docString.getSummary());
final List<Section> sections = docString.getSections();
assertSize(3, sections);
@@ -83,6 +79,15 @@ public class PyGoogleCodeStyleDocStringTest extends PyTestCase {
assertEquals("always", firstReturnField.getDescription().toString());
}
@NotNull
private GoogleCodeStyleDocString findAndParseDocString() {
myFixture.configureByFile(getTestName(true) + ".py");
final String docStringText = findFirstDocString();
assertNotNull(docStringText);
return new GoogleCodeStyleDocString(docStringText);
}
@Nullable
private String findFirstDocString() {
final PsiElementProcessor.FindElement<PsiElement> processor = new PsiElementProcessor.FindElement<PsiElement>() {
@@ -104,10 +109,7 @@ public class PyGoogleCodeStyleDocStringTest extends PyTestCase {
}
public void testSectionStartAfterQuotes() {
myFixture.configureByFile(getTestName(true) + ".py");
final String docStringText = findFirstDocString();
assertNotNull(docStringText);
final GoogleCodeStyleDocString docString = new GoogleCodeStyleDocString(docStringText);
final GoogleCodeStyleDocString docString = findAndParseDocString();
assertEmpty(docString.getSummary());
assertSize(2, docString.getSections());
@@ -128,10 +130,36 @@ public class PyGoogleCodeStyleDocStringTest extends PyTestCase {
final SectionField firstNotesField = notesSection.getFields().get(0);
assertNull(firstNotesField.getName());
assertNull(firstNotesField.getType());
assertNotNull(firstNotesField.getDescription());
assertEquals(" some\n" +
" notes", firstNotesField.getDescription().toString());
}
public void testTypeReferences() {
final GoogleCodeStyleDocString docString = findAndParseDocString();
assertEmpty(docString.getSummary());
assertSize(2, docString.getSections());
final Section paramSection = docString.getSections().get(0);
assertSize(1, paramSection.getFields());
final SectionField param1 = paramSection.getFields().get(0);
assertNotNull(param1.getName());
assertEquals("a1", param1.getName().toString());
assertNotNull(param1.getType());
assertEquals(":class:`MyClass`", param1.getType().toString());
assertNotNull(param1.getDescription());
assertEquals("used to call :def:`my_function` and access :attr:`my_attr`", param1.getDescription().toString());
final Section raisesSection = docString.getSections().get(1);
assertSize(1, raisesSection.getFields());
final SectionField exception1 = raisesSection.getFields().get(0);
assertNull(exception1.getName());
assertNotNull(exception1.getType());
assertEquals(":class:`MyException`", exception1.getType().toString());
assertNotNull(exception1.getDescription());
assertEquals("thrown in case of any error", exception1.getDescription().toString());
}
@Override
protected String getTestDataPath() {
return super.getTestDataPath() + "/docstrings";