From cc0ca5938c13541b650b2a542080d210b10e20cb Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Fri, 8 Jun 2018 16:06:59 +0300 Subject: [PATCH] PY-29386 reStructuredText code formatting breaks indents for .. toctree: --- .../com/jetbrains/rest/RestFormatterTest.java | 38 -- .../com/jetbrains/rest/RestLexerTest.java | 4 +- python/python-rest/testData/psi/Injection.txt | 8 +- python/python-rest/testData/psi/Reference.txt | 4 +- .../python-rest/testData/psi/Substitution.txt | 10 +- .../testData/structureView/fileBeginning.rst | 5 - .../structureView/oneInnerSection.rst | 14 - .../testData/structureView/plain.rst | 6 - .../testData/structureView/tree.rst | 30 -- .../jetbrains/rest/lexer/_RestFlexLexer.java | 348 ++++++++++-------- .../jetbrains/rest/formatter/RestBlock.java | 15 +- .../formatter/RestFormattingModelBuilder.java | 2 +- .../src/com/jetbrains/rest/lexer/rest.flex | 2 +- .../jetbrains/rest/parsing/RestParser.java | 24 +- .../testData/formatter/directive.rst | 0 .../testData/formatter/directive_after.rst | 0 python/rest/testData/formatter/field list.rst | 10 + .../testData/formatter/field list_after.rst | 10 + python/rest/testData/formatter/title.rst | 4 + .../rest/testData/formatter/title_after.rst | 4 + .../com/jetbrains/rest/RestFormatterTest.kt | 53 +++ 21 files changed, 313 insertions(+), 278 deletions(-) delete mode 100644 python/python-rest/test/com/jetbrains/rest/RestFormatterTest.java delete mode 100644 python/python-rest/testData/structureView/fileBeginning.rst delete mode 100644 python/python-rest/testData/structureView/oneInnerSection.rst delete mode 100644 python/python-rest/testData/structureView/plain.rst delete mode 100644 python/python-rest/testData/structureView/tree.rst rename python/{python-rest => rest}/testData/formatter/directive.rst (100%) rename python/{python-rest => rest}/testData/formatter/directive_after.rst (100%) create mode 100644 python/rest/testData/formatter/field list.rst create mode 100644 python/rest/testData/formatter/field list_after.rst create mode 100644 python/rest/testData/formatter/title.rst create mode 100644 python/rest/testData/formatter/title_after.rst create mode 100644 python/rest/tests/com/jetbrains/rest/RestFormatterTest.kt diff --git a/python/python-rest/test/com/jetbrains/rest/RestFormatterTest.java b/python/python-rest/test/com/jetbrains/rest/RestFormatterTest.java deleted file mode 100644 index 06438884468c..000000000000 --- a/python/python-rest/test/com/jetbrains/rest/RestFormatterTest.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2000-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.jetbrains.rest; - -import com.intellij.openapi.command.WriteCommandAction; -import com.intellij.psi.PsiFile; -import com.intellij.psi.codeStyle.CodeStyleManager; -import com.jetbrains.rest.fixtures.RestFixtureTestCase; - -public class RestFormatterTest extends RestFixtureTestCase { - - public void testDirective() { - doTest(); - } - - private void doTest() { - myFixture.configureByFile("formatter/" + getTestName(true) + ".rst"); - WriteCommandAction.runWriteCommandAction(null, () -> { - CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(myFixture.getProject()); - PsiFile file = myFixture.getFile(); - codeStyleManager.reformat(file); - }); - myFixture.checkResultByFile("formatter/" + getTestName(true) + "_after.rst"); - } -} diff --git a/python/python-rest/test/com/jetbrains/rest/RestLexerTest.java b/python/python-rest/test/com/jetbrains/rest/RestLexerTest.java index a7271af64ad7..7f580397d4e1 100644 --- a/python/python-rest/test/com/jetbrains/rest/RestLexerTest.java +++ b/python/python-rest/test/com/jetbrains/rest/RestLexerTest.java @@ -36,7 +36,7 @@ public class RestLexerTest extends TestCase { "[.. , EXPLISIT_MARKUP_START]", "[note::, DIRECTIVE]", "[\n, WHITESPACE]", - "[ , WHITESPACE]", + "[ , LINE]", "[Please, LINE]" ); } @@ -58,7 +58,7 @@ public class RestLexerTest extends TestCase { "[figure::, DIRECTIVE]", "[ image.png, LINE]", "[\n, WHITESPACE]", - "[ , WHITESPACE]", + "[ , LINE]", "[:width:, FIELD]", "[ , LINE]", "[300pt, LINE]" diff --git a/python/python-rest/testData/psi/Injection.txt b/python/python-rest/testData/psi/Injection.txt index 9a9b25fb0f67..de642498ca5d 100644 --- a/python/python-rest/testData/psi/Injection.txt +++ b/python/python-rest/testData/psi/Injection.txt @@ -1,6 +1,6 @@ rest file PsiElement(EXPLISIT_MARKUP_START)('.. ') - PsiElement(CUSTOM_DIRECTIVE)('code-block::') - PsiElement(WHITESPACE)('\n ') - RestLine:LINE_TEXT - PsiElement(LINE)('import datetime') \ No newline at end of file + RestDirective:DIRECTIVE_BLOCK + PsiElement(CUSTOM_DIRECTIVE)('code-block::') + PsiElement(WHITESPACE)('\n') + PsiElement(LINE)(' import datetime') \ No newline at end of file diff --git a/python/python-rest/testData/psi/Reference.txt b/python/python-rest/testData/psi/Reference.txt index e7ea920fb542..4d3dfa73c947 100644 --- a/python/python-rest/testData/psi/Reference.txt +++ b/python/python-rest/testData/psi/Reference.txt @@ -1,8 +1,6 @@ rest file RestLine:LINE_TEXT - PsiElement(LINE)('Many modern websites have the need for a threaded commenting system.') - PsiElement(WHITESPACE)(' ') - PsiElement(LINE)('Places') + PsiElement(LINE)('Many modern websites have the need for a threaded commenting system. Places') PsiElement(WHITESPACE)('\n') PsiElement(LINE)('like ') RestReference:REFERENCE_NAME diff --git a/python/python-rest/testData/psi/Substitution.txt b/python/python-rest/testData/psi/Substitution.txt index 0a5174bc3e77..625400b6ab0c 100644 --- a/python/python-rest/testData/psi/Substitution.txt +++ b/python/python-rest/testData/psi/Substitution.txt @@ -6,6 +6,10 @@ rest file RestDirective:DIRECTIVE_BLOCK PsiElement(DIRECTIVE)('image::') PsiElement(LINE)(' warning.png') - PsiElement(WHITESPACE)('\n ') - PsiElement(FIELD)(':alt:') - PsiElement(LINE)(' Warning!') \ No newline at end of file + PsiElement(WHITESPACE)('\n') + PsiElement(LINE)(' ') + RestFieldList:FIELD_LIST + RestRole:FIELD + PsiElement(FIELD)(':alt:') + RestLine:LINE_TEXT + PsiElement(LINE)(' Warning!') \ No newline at end of file diff --git a/python/python-rest/testData/structureView/fileBeginning.rst b/python/python-rest/testData/structureView/fileBeginning.rst deleted file mode 100644 index 30a64da355e1..000000000000 --- a/python/python-rest/testData/structureView/fileBeginning.rst +++ /dev/null @@ -1,5 +0,0 @@ -Chapter 1 Title -=============== - -Chapter 2 Title -=============== diff --git a/python/python-rest/testData/structureView/oneInnerSection.rst b/python/python-rest/testData/structureView/oneInnerSection.rst deleted file mode 100644 index 7ab4056d29f8..000000000000 --- a/python/python-rest/testData/structureView/oneInnerSection.rst +++ /dev/null @@ -1,14 +0,0 @@ -Chapter 1 Title -=============== - -Section 1.1 Title ------------------ - -Subsection 1.1.1 Title -~~~~~~~~~~~~~~~~~~~~~~ - -Section 1.2 Title ------------------ - -Chapter 2 Title -=============== diff --git a/python/python-rest/testData/structureView/plain.rst b/python/python-rest/testData/structureView/plain.rst deleted file mode 100644 index b58c1a1ae236..000000000000 --- a/python/python-rest/testData/structureView/plain.rst +++ /dev/null @@ -1,6 +0,0 @@ - -Chapter 1 Title -=============== - -Chapter 2 Title -=============== diff --git a/python/python-rest/testData/structureView/tree.rst b/python/python-rest/testData/structureView/tree.rst deleted file mode 100644 index 50de5d685f3b..000000000000 --- a/python/python-rest/testData/structureView/tree.rst +++ /dev/null @@ -1,30 +0,0 @@ - -The following document: - -============ -Hello, world -============ - -A section -========= - -A subsection ------------- - -A sub-subsection -```````````````` - -An other one -```````````` - -Back up -======= - -And down --------- - -twice ------ - -with feelings -````````````` diff --git a/python/rest/gen/com/jetbrains/rest/lexer/_RestFlexLexer.java b/python/rest/gen/com/jetbrains/rest/lexer/_RestFlexLexer.java index d03c0caf0ebc..469d1358497a 100644 --- a/python/rest/gen/com/jetbrains/rest/lexer/_RestFlexLexer.java +++ b/python/rest/gen/com/jetbrains/rest/lexer/_RestFlexLexer.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex 1.7.0-SNAPSHOT tweaked for IntelliJ platform */ +/* The following code was generated by JFlex 1.7.0 tweaked for IntelliJ platform */ package com.jetbrains.rest.lexer; @@ -10,7 +10,7 @@ import com.jetbrains.rest.RestTokenTypes; /** * This class is a scanner generated by - * JFlex 1.7.0-SNAPSHOT + * JFlex 1.7.0 * from the specification file rest.flex */ public class _RestFlexLexer implements FlexLexer, RestTokenTypes { @@ -97,35 +97,35 @@ public class _RestFlexLexer implements FlexLexer, RestTokenTypes { "\2\0\1\6\1\0\1\6\1\0\13\6\1\0\5\6"+ "\1\0\2\6\4\0\6\6\1\0\1\32\2\0\2\6"+ "\1\33\2\27\1\0\1\27\1\0\2\34\5\0\1\31"+ - "\3\0\2\25\35\0\2\25\42\0\4\6\2\0\3\6"+ - "\1\0\2\6\3\0\1\6\1\0\3\6\1\0\3\6"+ - "\1\0\4\6\1\0\3\6\2\0\6\6\1\0\2\6"+ - "\4\0\7\6\1\32\1\35\26\0\1\36\6\0\1\37"+ - "\3\0\2\40\2\0\2\41\36\0\1\36\2\0\1\36"+ - "\57\0\1\37\22\0\3\40\21\0\1\42\3\6\3\0"+ - "\1\6\1\0\1\6\1\0\1\6\2\0\1\6\1\0"+ - "\3\6\2\0\2\6\2\0\4\6\1\0\1\6\1\0"+ - "\1\6\1\0\3\6\1\0\2\6\3\0\5\6\1\37"+ - "\2\0\1\43\14\0\3\44\1\45\1\46\2\0\1\41"+ - "\1\0\2\41\3\0\1\36\30\0\3\41\37\0\1\41"+ - "\1\0\3\44\1\45\1\46\12\0\1\46\2\0\1\41"+ - "\20\0\1\32\1\41\1\0\3\47\2\6\2\50\1\0"+ - "\1\6\3\0\1\6\1\0\2\6\1\0\1\6\1\0"+ - "\1\6\1\0\3\6\1\0\1\6\1\0\1\6\1\0"+ - "\1\6\2\0\2\6\4\0\5\6\2\0\3\51\3\52"+ - "\4\0\1\51\4\0\3\41\21\0\1\41\1\0\1\51"+ - "\1\41\1\0\1\51\1\41\17\0\1\41\5\0\1\6"+ - "\1\0\1\6\2\0\1\6\2\0\2\6\1\0\1\6"+ + "\3\0\1\25\1\35\35\0\1\25\1\35\42\0\4\6"+ + "\2\0\3\6\1\0\2\6\3\0\1\6\1\0\3\6"+ + "\1\0\3\6\1\0\4\6\1\0\3\6\2\0\6\6"+ + "\1\0\2\6\4\0\7\6\1\32\1\36\26\0\1\37"+ + "\6\0\1\40\3\0\2\41\2\0\2\42\36\0\1\37"+ + "\2\0\1\37\57\0\1\40\22\0\3\41\21\0\1\43"+ + "\3\6\3\0\1\6\1\0\1\6\1\0\1\6\2\0"+ + "\1\6\1\0\3\6\2\0\2\6\2\0\4\6\1\0"+ + "\1\6\1\0\1\6\1\0\3\6\1\0\2\6\3\0"+ + "\5\6\1\40\2\0\1\44\14\0\3\45\1\46\1\47"+ + "\2\0\1\42\1\0\2\42\3\0\1\37\30\0\3\42"+ + "\37\0\1\42\1\0\3\45\1\46\1\47\12\0\1\47"+ + "\2\0\1\42\20\0\1\32\1\42\1\0\3\50\2\6"+ + "\2\51\1\0\1\6\3\0\1\6\1\0\2\6\1\0"+ + "\1\6\1\0\1\6\1\0\3\6\1\0\1\6\1\0"+ + "\1\6\1\0\1\6\2\0\2\6\4\0\5\6\2\0"+ + "\3\52\3\53\4\0\1\52\4\0\3\42\21\0\1\42"+ + "\1\0\1\52\1\42\1\0\1\52\1\42\17\0\1\42"+ + "\5\0\1\6\1\0\1\6\2\0\1\6\2\0\2\6"+ "\1\0\1\6\1\0\1\6\1\0\1\6\1\0\1\6"+ - "\1\0\1\6\2\0\2\6\4\0\4\6\3\53\1\54"+ - "\1\55\2\0\1\54\1\41\1\0\1\54\1\55\1\41"+ - "\1\0\1\55\5\0\1\6\4\0\2\6\1\0\1\6"+ - "\1\0\1\6\1\0\1\6\3\0\1\6\2\0\3\6"+ - "\7\0\1\6\1\0\1\6\6\0\1\6\3\56\5\0"+ - "\1\6\1\0\1\6\5\0\1\6\15\56\4\0\1\6"+ - "\6\0\1\6\1\41\2\0\1\6\2\57\5\0\1\6"+ - "\5\0\1\6\5\0\1\6\3\0\1\6\3\0\1\6"+ - "\42\0"; + "\1\0\1\6\1\0\1\6\2\0\2\6\4\0\4\6"+ + "\3\54\1\55\1\56\2\0\1\55\1\42\1\0\1\55"+ + "\1\56\1\42\1\0\1\56\5\0\1\6\4\0\2\6"+ + "\1\0\1\6\1\0\1\6\1\0\1\6\3\0\1\6"+ + "\2\0\3\6\7\0\1\6\1\0\1\6\6\0\1\6"+ + "\3\57\5\0\1\6\1\0\1\6\5\0\1\6\15\57"+ + "\4\0\1\6\6\0\1\6\1\42\2\0\1\6\2\60"+ + "\5\0\1\6\5\0\1\6\5\0\1\6\3\0\1\6"+ + "\3\0\1\6\42\0"; private static int [] zzUnpackAction() { int [] result = new int[964]; @@ -1868,11 +1868,11 @@ public class _RestFlexLexer implements FlexLexer, RestTokenTypes { if (zzMarkedPosL > zzStartRead) { switch (zzBufferL.charAt(zzMarkedPosL-1)) { case '\n': - case '\u000B': - case '\u000C': - case '\u0085': - case '\u2028': - case '\u2029': + case '\u000B': // fall though + case '\u000C': // fall though + case '\u0085': // fall though + case '\u2028': // fall though + case '\u2029': // fall though zzAtBOL = true; break; case '\r': @@ -1966,116 +1966,143 @@ public class _RestFlexLexer implements FlexLexer, RestTokenTypes { switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { case 1: { yybegin(IN_INLINE); return LINE; - } - case 48: break; + } + // fall through + case 49: break; case 2: { yypushback(1); yybegin(INIT); - } - case 49: break; + } + // fall through + case 50: break; case 3: { yybegin(INIT); return WHITESPACE; - } - case 50: break; + } + // fall through + case 51: break; case 4: { yybegin(INIT); return ERROR; - } - case 51: break; + } + // fall through + case 52: break; case 5: { return WHITESPACE; - } - case 52: break; + } + // fall through + case 53: break; case 6: { yybegin(IN_COMMENT); return COMMENT; - } - case 53: break; + } + // fall through + case 54: break; case 7: { return COMMENT; - } - case 54: break; + } + // fall through + case 55: break; case 8: { yybegin(PRE_INDENTED); myIndent = yylength(); return chooseType(); - } - case 55: break; + } + // fall through + case 56: break; case 9: { yybegin(PRE_QUOTED); return SPEC_SYMBOL; - } - case 56: break; + } + // fall through + case 57: break; case 10: { yypushback(1); myIndent = 0; myState = 0; yybegin(INIT); - } - case 57: break; + } + // fall through + case 58: break; case 11: { return chooseType(); - } - case 58: break; + } + // fall through + case 59: break; case 12: { if (yylength() >= myIndent) { yybegin(PRE_INDENTED); return chooseType();} else { myIndent = 0; yypushback(yylength()); yybegin(INIT); } - } - case 59: break; + } + // fall through + case 60: break; case 13: { yybegin(INDENTED); return chooseType(); - } - case 60: break; + } + // fall through + case 61: break; case 14: { yypushback(1); myState = 0; yybegin(INIT); - } - case 61: break; + } + // fall through + case 62: break; case 15: { yybegin(PRE_QUOTED); return chooseType(); - } - case 62: break; + } + // fall through + case 63: break; case 16: { yybegin(QUOTED); return chooseType(); - } - case 63: break; + } + // fall through + case 64: break; case 17: { yybegin(INIT); return LINE; - } - case 64: break; + } + // fall through + case 65: break; case 18: { yybegin(IN_FOOTNOTE); return LINE; - } - case 65: break; + } + // fall through + case 66: break; case 19: { return LINE; - } - case 66: break; + } + // fall through + case 67: break; case 20: { yypushback(1); yybegin(IN_LINE); - } - case 67: break; + } + // fall through + case 68: break; case 21: { yybegin(IN_LINEBEGIN); return WHITESPACE; - } - case 68: break; + } + // fall through + case 69: break; case 22: { yybegin(IN_LINE); return SPEC_SYMBOL; - } - case 69: break; + } + // fall through + case 70: break; case 23: { yybegin(INIT); return COMMENT; - } - case 70: break; + } + // fall through + case 71: break; case 24: { yybegin(IN_VALUE); return CUSTOM_DIRECTIVE; - } - case 71: break; + } + // fall through + case 72: break; case 25: { yybegin(IN_VALUE); return ANONYMOUS_HYPERLINK; - } - case 72: break; + } + // fall through + case 73: break; case 26: { return SUBSTITUTION; - } - case 73: break; + } + // fall through + case 74: break; case 27: { yybegin(INIT); return FOOTNOTE; - } - case 74: break; + } + // fall through + case 75: break; case 28: { String value = yytext().toString().trim(); if ("python".equalsIgnoreCase(value)) { @@ -2095,84 +2122,109 @@ public class _RestFlexLexer implements FlexLexer, RestTokenTypes { yybegin(INIT); } return LINE; - } - case 75: break; - case 29: - { yybegin(INIT); return CITATION; - } + } + // fall through case 76: break; - case 30: - { return INTERPRETED; - } + case 29: + { yybegin(IN_LINEBEGIN); return LINE; + } + // fall through case 77: break; - case 31: - { yybegin(IN_EXPLISIT_MARKUP); return EXPLISIT_MARKUP_START; - } + case 30: + { yybegin(INIT); return CITATION; + } + // fall through case 78: break; - case 32: - { yypushback(1); return REFERENCE_NAME; - } + case 31: + { return INTERPRETED; + } + // fall through case 79: break; - case 33: - { return TITLE; - } + case 32: + { yybegin(IN_EXPLISIT_MARKUP); return EXPLISIT_MARKUP_START; + } + // fall through case 80: break; - case 34: - { yybegin(INIT); return HYPERLINK; - } + case 33: + { yypushback(1); return REFERENCE_NAME; + } + // fall through case 81: break; - case 35: - { yypushback(1); yybegin(INIT); return REFERENCE_NAME; - } + case 34: + { return TITLE; + } + // fall through case 82: break; - case 36: - { yybegin(IN_INLINE);return LITERAL_BLOCK_START; - } + case 35: + { yybegin(INIT); return HYPERLINK; + } + // fall through case 83: break; - case 37: - { yypushback(yylength()-1); return LINE; - } + case 36: + { yypushback(1); yybegin(INIT); return REFERENCE_NAME; + } + // fall through case 84: break; - case 38: - { return ITALIC; - } + case 37: + { yybegin(IN_INLINE);return LITERAL_BLOCK_START; + } + // fall through case 85: break; - case 39: - { yypushback(1); return FIELD; - } + case 38: + { yypushback(yylength()-1); return LINE; + } + // fall through case 86: break; - case 40: - { yybegin(IN_VALUE); return DIRECTIVE; - } + case 39: + { return ITALIC; + } + // fall through case 87: break; - case 41: - { yypushback(1); yybegin(INIT); return FIELD; - } + case 40: + { yypushback(1); return FIELD; + } + // fall through case 88: break; - case 42: - { yypushback(1); yybegin(FIELD_LINE); return FIELD; - } + case 41: + { yybegin(IN_VALUE); return DIRECTIVE; + } + // fall through case 89: break; - case 43: - { yypushback(yylength()-1); yybegin(FIELD_IN_INLINE); return WHITESPACE; - } + case 42: + { yypushback(1); yybegin(INIT); return FIELD; + } + // fall through case 90: break; - case 44: - { return FIXED; - } + case 43: + { yypushback(1); yybegin(FIELD_LINE); return FIELD; + } + // fall through case 91: break; - case 45: - { return BOLD; - } + case 44: + { yypushback(yylength()-1); yybegin(FIELD_IN_INLINE); return WHITESPACE; + } + // fall through case 92: break; - case 46: - { return DIRECT_HYPERLINK; - } + case 45: + { return FIXED; + } + // fall through case 93: break; - case 47: - { yybegin(IN_HIGHLIGHT); return CUSTOM_DIRECTIVE; - } + case 46: + { return BOLD; + } + // fall through case 94: break; + case 47: + { return DIRECT_HYPERLINK; + } + // fall through + case 95: break; + case 48: + { yybegin(IN_HIGHLIGHT); return CUSTOM_DIRECTIVE; + } + // fall through + case 96: break; default: zzScanError(ZZ_NO_MATCH); } diff --git a/python/rest/src/com/jetbrains/rest/formatter/RestBlock.java b/python/rest/src/com/jetbrains/rest/formatter/RestBlock.java index fb922d2b1468..cff7b3e9f5f9 100644 --- a/python/rest/src/com/jetbrains/rest/formatter/RestBlock.java +++ b/python/rest/src/com/jetbrains/rest/formatter/RestBlock.java @@ -30,15 +30,13 @@ import java.util.Collections; import java.util.List; public class RestBlock implements ASTBlock { - private final RestBlock myParent; private final ASTNode myNode; private final Alignment myAlignment; private final Indent myIndent; private final Wrap myWrap; private List mySubBlocks = null; - public RestBlock(RestBlock parent, ASTNode node, final Alignment alignment, Indent indent, Wrap wrap) { - myParent = parent; + public RestBlock(ASTNode node, final Alignment alignment, Indent indent, Wrap wrap) { myNode = node; myAlignment = alignment; myIndent = indent; @@ -80,21 +78,14 @@ public class RestBlock implements ASTBlock { } private RestBlock buildSubBlock(ASTNode child) { - IElementType parentType = myNode.getElementType(); IElementType childType = child.getElementType(); IElementType grandparentType = myNode.getTreeParent() == null ? null : myNode.getTreeParent().getElementType(); - Wrap wrap = null; Indent childIndent = Indent.getNoneIndent(); - Alignment childAlignment = null; - if (grandparentType == RestElementTypes.FIELD_LIST && parentType == RestElementTypes.LINE_TEXT && - childType == RestTokenTypes.LINE) { + if (grandparentType == RestElementTypes.DIRECTIVE_BLOCK && childType == RestTokenTypes.FIELD) { childIndent = Indent.getNormalIndent(); } - if (parentType == RestElementTypes.DIRECTIVE_BLOCK && childType == RestTokenTypes.FIELD) { - childIndent = Indent.getNormalIndent(); - } - return new RestBlock(this, child, childAlignment, childIndent, wrap); + return new RestBlock(child, null, childIndent, null); } diff --git a/python/rest/src/com/jetbrains/rest/formatter/RestFormattingModelBuilder.java b/python/rest/src/com/jetbrains/rest/formatter/RestFormattingModelBuilder.java index cb9a175921ff..fe80a25bcd7d 100644 --- a/python/rest/src/com/jetbrains/rest/formatter/RestFormattingModelBuilder.java +++ b/python/rest/src/com/jetbrains/rest/formatter/RestFormattingModelBuilder.java @@ -53,7 +53,7 @@ public class RestFormattingModelBuilder implements FormattingModelBuilderEx, Cus @NotNull CodeStyleSettings settings, @NotNull FormattingMode mode) { - final RestBlock block = new RestBlock(null, element.getNode(), null, Indent.getNoneIndent(), null); + final RestBlock block = new RestBlock(element.getNode(), null, Indent.getNoneIndent(), null); return FormattingModelProvider.createFormattingModelForPsiFile(element.getContainingFile(), block, settings); } diff --git a/python/rest/src/com/jetbrains/rest/lexer/rest.flex b/python/rest/src/com/jetbrains/rest/lexer/rest.flex index 6df9cd7007bf..e0fed8210d1d 100644 --- a/python/rest/src/com/jetbrains/rest/lexer/rest.flex +++ b/python/rest/src/com/jetbrains/rest/lexer/rest.flex @@ -94,7 +94,7 @@ LINK = [0-9A-Za-z][0-9A-Za-z\-:+_]*"_""_"? ":"[^:\n\r ]([^:\n\r] | "\\:")*[^:\n\r ]":"[`] { yypushback(1); yybegin(INIT); return FIELD;} {CRLF} { yybegin(IN_LINEBEGIN); return WHITESPACE;} . { yypushback(1); yybegin(IN_LINE); } -{SPACE}+ { yybegin(IN_LINEBEGIN); return WHITESPACE;} +{SPACE}+ { yybegin(IN_LINEBEGIN); return LINE;} } { diff --git a/python/rest/src/com/jetbrains/rest/parsing/RestParser.java b/python/rest/src/com/jetbrains/rest/parsing/RestParser.java index 98d79a387cf1..a9ad69661654 100644 --- a/python/rest/src/com/jetbrains/rest/parsing/RestParser.java +++ b/python/rest/src/com/jetbrains/rest/parsing/RestParser.java @@ -34,7 +34,6 @@ public class RestParser implements PsiParser { while (!builder.eof()) { IElementType type = builder.getTokenType(); if (type == RestTokenTypes.EXPLISIT_MARKUP_START) { - builder.advanceLexer(); parseMarkup(builder); } else if (type == RestTokenTypes.REFERENCE_NAME || type == RestTokenTypes.SUBSTITUTION) { @@ -75,6 +74,10 @@ public class RestParser implements PsiParser { PsiBuilder.Marker marker = builder.mark(); boolean gotLine = false; while (type == RestTokenTypes.LINE || type == RestTokenTypes.WHITESPACE) { + final IElementType nextType = builder.lookAhead(1); + if (nextType != RestTokenTypes.LINE && type == RestTokenTypes.WHITESPACE) { + break; + } builder.advanceLexer(); type = builder.getTokenType(); gotLine = true; @@ -102,6 +105,7 @@ public class RestParser implements PsiParser { } private static void parseMarkup(PsiBuilder builder) { + builder.advanceLexer(); PsiBuilder.Marker marker = builder.mark(); IElementType type = builder.getTokenType(); if (type == RestTokenTypes.SUBSTITUTION) { @@ -111,7 +115,7 @@ public class RestParser implements PsiParser { marker = builder.mark(); type = builder.getTokenType(); } - if (type == RestTokenTypes.DIRECTIVE) { + if (type == RestTokenTypes.DIRECTIVE || type == RestTokenTypes.CUSTOM_DIRECTIVE) { gotoNextWhiteSpaces(builder); if (builder.getTokenType() != RestTokenTypes.WHITESPACE) { builder.advanceLexer(); @@ -120,7 +124,7 @@ public class RestParser implements PsiParser { } skipBlankLines(builder); final String tokenText = builder.getTokenText(); - if (builder.getTokenType() != RestTokenTypes.WHITESPACE || + if (builder.getTokenType() != RestTokenTypes.LINE || (tokenText != null && StringUtil.getLineBreakCount(tokenText) == tokenText.length())) { marker.done(RestElementTypes.DIRECTIVE_BLOCK); return; @@ -151,17 +155,15 @@ public class RestParser implements PsiParser { } } - private static void parseDirective(PsiBuilder builder, String white, PsiBuilder.Marker marker) { - gotoNextWhiteSpaces(builder); - if (builder.getTokenType() != RestTokenTypes.WHITESPACE) { - builder.advanceLexer(); - marker.done(RestElementTypes.DIRECTIVE_BLOCK); - return; + private static void parseDirective(PsiBuilder builder, String indent, PsiBuilder.Marker marker) { + while (builder.getTokenType() == RestTokenTypes.FIELD) { + parseFieldList(builder); } + gotoNextWhiteSpaces(builder); skipBlankLines(builder); - if (white.equals(builder.getTokenText())) { + if (indent.equals(builder.getTokenText())) { builder.advanceLexer(); - parseDirective(builder, white, marker); + parseDirective(builder, indent, marker); } else { marker.done(RestElementTypes.DIRECTIVE_BLOCK); diff --git a/python/python-rest/testData/formatter/directive.rst b/python/rest/testData/formatter/directive.rst similarity index 100% rename from python/python-rest/testData/formatter/directive.rst rename to python/rest/testData/formatter/directive.rst diff --git a/python/python-rest/testData/formatter/directive_after.rst b/python/rest/testData/formatter/directive_after.rst similarity index 100% rename from python/python-rest/testData/formatter/directive_after.rst rename to python/rest/testData/formatter/directive_after.rst diff --git a/python/rest/testData/formatter/field list.rst b/python/rest/testData/formatter/field list.rst new file mode 100644 index 000000000000..6bc9a7f336ec --- /dev/null +++ b/python/rest/testData/formatter/field list.rst @@ -0,0 +1,10 @@ + + +.. include:: readme.rst + +.. toctree:: + :maxdepth: 4 + + getting-started + tutorials + contributors diff --git a/python/rest/testData/formatter/field list_after.rst b/python/rest/testData/formatter/field list_after.rst new file mode 100644 index 000000000000..6bc9a7f336ec --- /dev/null +++ b/python/rest/testData/formatter/field list_after.rst @@ -0,0 +1,10 @@ + + +.. include:: readme.rst + +.. toctree:: + :maxdepth: 4 + + getting-started + tutorials + contributors diff --git a/python/rest/testData/formatter/title.rst b/python/rest/testData/formatter/title.rst new file mode 100644 index 000000000000..4e1852549a37 --- /dev/null +++ b/python/rest/testData/formatter/title.rst @@ -0,0 +1,4 @@ +``a_function()`` +---------------- + +:Author: David Goodger \ No newline at end of file diff --git a/python/rest/testData/formatter/title_after.rst b/python/rest/testData/formatter/title_after.rst new file mode 100644 index 000000000000..4e1852549a37 --- /dev/null +++ b/python/rest/testData/formatter/title_after.rst @@ -0,0 +1,4 @@ +``a_function()`` +---------------- + +:Author: David Goodger \ No newline at end of file diff --git a/python/rest/tests/com/jetbrains/rest/RestFormatterTest.kt b/python/rest/tests/com/jetbrains/rest/RestFormatterTest.kt new file mode 100644 index 000000000000..f772e196fb97 --- /dev/null +++ b/python/rest/tests/com/jetbrains/rest/RestFormatterTest.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jetbrains.rest + +import com.intellij.openapi.command.WriteCommandAction +import com.intellij.psi.codeStyle.CodeStyleManager +import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase + +class RestFormatterTest : LightPlatformCodeInsightFixtureTestCase() { + + fun `test directive`() { + doTest() + } + + fun `test title`() { + doTest() + } + + fun `test field list`() { + doTest() + } + + private fun doTest() { + val testName = getTestName(true).trim() + myFixture.configureByFile("formatter/$testName.rst") + WriteCommandAction.runWriteCommandAction(null) { + val codeStyleManager = CodeStyleManager.getInstance(myFixture.project) + val file = myFixture.file + codeStyleManager.reformat(file) + } + myFixture.checkResultByFile("formatter/${testName}_after.rst") + } + + + override fun getBasePath(): String { + return "python/rest/testData" + } + + override fun isCommunity(): Boolean = true +}