mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-15 02:59:33 +07:00
tweak alignment of comments between classes (PY-1598)
This commit is contained in:
@@ -6,6 +6,7 @@ import com.intellij.openapi.editor.Document;
|
|||||||
import com.intellij.openapi.util.TextRange;
|
import com.intellij.openapi.util.TextRange;
|
||||||
import com.intellij.psi.*;
|
import com.intellij.psi.*;
|
||||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||||
|
import com.intellij.psi.impl.source.tree.TreeUtil;
|
||||||
import com.intellij.psi.tree.IElementType;
|
import com.intellij.psi.tree.IElementType;
|
||||||
import com.intellij.psi.tree.TokenSet;
|
import com.intellij.psi.tree.TokenSet;
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
@@ -118,7 +119,7 @@ public class PyBlock implements ASTBlock {
|
|||||||
Indent childIndent = Indent.getNoneIndent();
|
Indent childIndent = Indent.getNoneIndent();
|
||||||
Alignment childAlignment = null;
|
Alignment childAlignment = null;
|
||||||
if (childType == PyElementTypes.STATEMENT_LIST || childType == PyElementTypes.IMPORT_ELEMENT) {
|
if (childType == PyElementTypes.STATEMENT_LIST || childType == PyElementTypes.IMPORT_ELEMENT) {
|
||||||
if (hasLineBreakBefore(child)) {
|
if (hasLineBreaksBefore(child, 1)) {
|
||||||
childIndent = Indent.getNormalIndent();
|
childIndent = Indent.getNormalIndent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,18 +165,26 @@ public class PyBlock implements ASTBlock {
|
|||||||
childAlignment = getAlignmentForChildren();
|
childAlignment = getAlignmentForChildren();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try { // maybe enter was pressed and cut us from a previous (nested) statement list
|
|
||||||
|
if (isAfterStatementList(child) && !hasLineBreaksBefore(child, 2)) { // maybe enter was pressed and cut us from a previous (nested) statement list
|
||||||
|
childIndent = Indent.getNormalIndent();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new PyBlock(child, childAlignment, childIndent, wrap, mySettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isAfterStatementList(ASTNode child) {
|
||||||
|
try {
|
||||||
PsiElement prev = sure(child.getPsi().getPrevSibling());
|
PsiElement prev = sure(child.getPsi().getPrevSibling());
|
||||||
sure(prev instanceof PyStatement);
|
sure(prev instanceof PyStatement);
|
||||||
PsiElement lastchild = PsiTreeUtil.getDeepestLast(prev);
|
PsiElement lastchild = PsiTreeUtil.getDeepestLast(prev);
|
||||||
sure(lastchild.getParent() instanceof PyStatementList);
|
sure(lastchild.getParent() instanceof PyStatementList);
|
||||||
childIndent = Indent.getNormalIndent();
|
return true;
|
||||||
}
|
}
|
||||||
catch (IncorrectOperationException ignored) {
|
catch (IncorrectOperationException e) {
|
||||||
// not our cup of tea
|
// not our cup of tea
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new PyBlock(child, childAlignment, childIndent, wrap, mySettings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean needListAlignment(ASTNode child) {
|
private static boolean needListAlignment(ASTNode child) {
|
||||||
@@ -189,15 +198,22 @@ public class PyBlock implements ASTBlock {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean hasLineBreakBefore(ASTNode child) {
|
private static boolean hasLineBreaksBefore(ASTNode child, int minCount) {
|
||||||
return isWhitespaceWithLineBreaks(child.getTreePrev()) || isWhitespaceWithLineBreaks(child.getFirstChildNode());
|
return isWhitespaceWithLineBreaks(TreeUtil.findLastLeaf(child.getTreePrev()), minCount) ||
|
||||||
|
isWhitespaceWithLineBreaks(child.getFirstChildNode(), minCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isWhitespaceWithLineBreaks(ASTNode node) {
|
private static boolean isWhitespaceWithLineBreaks(ASTNode node, int minCount) {
|
||||||
if (node != null && node.getElementType() == TokenType.WHITE_SPACE) {
|
if (node != null && node.getElementType() == TokenType.WHITE_SPACE) {
|
||||||
String prevNodeText = node.getText();
|
String prevNodeText = node.getText();
|
||||||
if (prevNodeText.indexOf('\n') >= 0) {
|
int count = 0;
|
||||||
return true;
|
for(int i=0; i<prevNodeText.length(); i++) {
|
||||||
|
if (prevNodeText.charAt(i) == '\n') {
|
||||||
|
count++;
|
||||||
|
if (count == minCount) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -412,7 +428,7 @@ public class PyBlock implements ASTBlock {
|
|||||||
// doesn't request childAttributes from the correct block
|
// doesn't request childAttributes from the correct block
|
||||||
while (lastChild != null) {
|
while (lastChild != null) {
|
||||||
IElementType last_type = lastChild.getElementType();
|
IElementType last_type = lastChild.getElementType();
|
||||||
if (last_type == PyElementTypes.STATEMENT_LIST && hasLineBreakBefore(lastChild)) {
|
if (last_type == PyElementTypes.STATEMENT_LIST && hasLineBreaksBefore(lastChild, 1)) {
|
||||||
if (dedentAfterLastStatement((PyStatementList)lastChild.getPsi())) {
|
if (dedentAfterLastStatement((PyStatementList)lastChild.getPsi())) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
9
python/testData/formatter/commentBetweenClasses.py
Normal file
9
python/testData/formatter/commentBetweenClasses.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
class T1(object):
|
||||||
|
def m1(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# comment about T2
|
||||||
|
|
||||||
|
class T2(object):
|
||||||
|
def m2(self):
|
||||||
|
pass
|
||||||
9
python/testData/formatter/commentBetweenClasses_after.py
Normal file
9
python/testData/formatter/commentBetweenClasses_after.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
class T1(object):
|
||||||
|
def m1(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# comment about T2
|
||||||
|
|
||||||
|
class T2(object):
|
||||||
|
def m2(self):
|
||||||
|
pass
|
||||||
9
python/testData/psi/CommentBetweenClasses.py
Normal file
9
python/testData/psi/CommentBetweenClasses.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
class T1(object):
|
||||||
|
def m1(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# comment about T2
|
||||||
|
|
||||||
|
class T2(object):
|
||||||
|
def m2(self):
|
||||||
|
pass
|
||||||
56
python/testData/psi/CommentBetweenClasses.txt
Normal file
56
python/testData/psi/CommentBetweenClasses.txt
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
PyFile:CommentBetweenClasses.py
|
||||||
|
PyClass: T1
|
||||||
|
PsiElement(Py:CLASS_KEYWORD)('class')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(Py:IDENTIFIER)('T1')
|
||||||
|
PyArgumentList
|
||||||
|
PsiElement(Py:LPAR)('(')
|
||||||
|
PyReferenceExpression: object
|
||||||
|
PsiElement(Py:IDENTIFIER)('object')
|
||||||
|
PsiElement(Py:RPAR)(')')
|
||||||
|
PsiElement(Py:COLON)(':')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
PyStatementList
|
||||||
|
PyFunction('m1')
|
||||||
|
PsiElement(Py:DEF_KEYWORD)('def')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(Py:IDENTIFIER)('m1')
|
||||||
|
PyParameterList
|
||||||
|
PsiElement(Py:LPAR)('(')
|
||||||
|
PyNamedParameter('self')
|
||||||
|
PsiElement(Py:IDENTIFIER)('self')
|
||||||
|
PsiElement(Py:RPAR)(')')
|
||||||
|
PsiElement(Py:COLON)(':')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
PyStatementList
|
||||||
|
PyPassStatement
|
||||||
|
PsiElement(Py:PASS_KEYWORD)('pass')
|
||||||
|
PsiWhiteSpace('\n\n')
|
||||||
|
PsiComment(Py:END_OF_LINE_COMMENT)('# comment about T2')
|
||||||
|
PsiWhiteSpace('\n\n')
|
||||||
|
PyClass: T2
|
||||||
|
PsiElement(Py:CLASS_KEYWORD)('class')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(Py:IDENTIFIER)('T2')
|
||||||
|
PyArgumentList
|
||||||
|
PsiElement(Py:LPAR)('(')
|
||||||
|
PyReferenceExpression: object
|
||||||
|
PsiElement(Py:IDENTIFIER)('object')
|
||||||
|
PsiElement(Py:RPAR)(')')
|
||||||
|
PsiElement(Py:COLON)(':')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
PyStatementList
|
||||||
|
PyFunction('m2')
|
||||||
|
PsiElement(Py:DEF_KEYWORD)('def')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(Py:IDENTIFIER)('m2')
|
||||||
|
PyParameterList
|
||||||
|
PsiElement(Py:LPAR)('(')
|
||||||
|
PyNamedParameter('self')
|
||||||
|
PsiElement(Py:IDENTIFIER)('self')
|
||||||
|
PsiElement(Py:RPAR)(')')
|
||||||
|
PsiElement(Py:COLON)(':')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
PyStatementList
|
||||||
|
PyPassStatement
|
||||||
|
PsiElement(Py:PASS_KEYWORD)('pass')
|
||||||
@@ -88,6 +88,10 @@ public class PyFormatterTest extends PyLightFixtureTestCase {
|
|||||||
doTest();
|
doTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testCommentBetweenClasses() { // PY-1598
|
||||||
|
doTest();
|
||||||
|
}
|
||||||
|
|
||||||
private void doTest() {
|
private void doTest() {
|
||||||
myFixture.configureByFile("formatter/" + getTestName(true) + ".py");
|
myFixture.configureByFile("formatter/" + getTestName(true) + ".py");
|
||||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||||
|
|||||||
@@ -235,6 +235,10 @@ public class PythonParsingTest extends ParsingTestCase {
|
|||||||
doTest();
|
doTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testCommentBetweenClasses() { // PY-1598
|
||||||
|
doTest();
|
||||||
|
}
|
||||||
|
|
||||||
public void doTest() {
|
public void doTest() {
|
||||||
doTest(LanguageLevel.PYTHON25);
|
doTest(LanguageLevel.PYTHON25);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user