diff --git a/python/rest/resources/META-INF/rest.xml b/python/rest/resources/META-INF/rest.xml
index b8e5f8db5da1..0887f8ca65e5 100644
--- a/python/rest/resources/META-INF/rest.xml
+++ b/python/rest/resources/META-INF/rest.xml
@@ -14,7 +14,7 @@
-
+
diff --git a/python/rest/src/com/jetbrains/rest/RestElementTypes.java b/python/rest/src/com/jetbrains/rest/RestElementTypes.java
index 8a0dddade12f..9cc55bb26437 100644
--- a/python/rest/src/com/jetbrains/rest/RestElementTypes.java
+++ b/python/rest/src/com/jetbrains/rest/RestElementTypes.java
@@ -12,5 +12,6 @@ public interface RestElementTypes {
RestElementType INLINE_BLOCK = new RestElementType("INLINE_BLOCK");
RestElementType LINE_TEXT = new RestElementType("LINE_TEXT");
+ RestElementType FIELD_LIST = new RestElementType("FIELD_LIST");
}
diff --git a/python/rest/src/com/jetbrains/rest/formatter/RestBlock.java b/python/rest/src/com/jetbrains/rest/formatter/RestBlock.java
new file mode 100644
index 000000000000..7e8814d0a4af
--- /dev/null
+++ b/python/rest/src/com/jetbrains/rest/formatter/RestBlock.java
@@ -0,0 +1,122 @@
+package com.jetbrains.rest.formatter;
+
+
+import com.intellij.formatting.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.tree.IElementType;
+import com.jetbrains.rest.RestElementTypes;
+import com.jetbrains.rest.RestTokenTypes;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class RestBlock implements ASTBlock {
+ private RestBlock myParent;
+ private ASTNode myNode;
+ private final Alignment myAlignment;
+ private final Indent myIndent;
+ private Wrap myWrap;
+ private List mySubBlocks = null;
+
+ public RestBlock(RestBlock parent, ASTNode node, final Alignment alignment, Indent indent, Wrap wrap) {
+ myParent = parent;
+ myNode = node;
+ myAlignment = alignment;
+ myIndent = indent;
+ myWrap = wrap;
+ }
+
+
+ @Override
+ public ASTNode getNode() {
+ return myNode;
+ }
+
+ @NotNull
+ @Override
+ public TextRange getTextRange() {
+ return myNode.getTextRange();
+ }
+
+ @NotNull
+ public List getSubBlocks() {
+ if (mySubBlocks == null) {
+ mySubBlocks = buildSubBlocks();
+ }
+ return new ArrayList(mySubBlocks);
+ }
+ private List buildSubBlocks() {
+ List blocks = new ArrayList();
+ for (ASTNode child = myNode.getFirstChildNode(); child != null; child = child.getTreeNext()) {
+
+ IElementType childType = child.getElementType();
+ if (child.getTextRange().getLength() == 0) continue;
+ if (childType == RestTokenTypes.WHITESPACE) {
+ continue;
+ }
+
+ blocks.add(buildSubBlock(child));
+ }
+ return Collections.unmodifiableList(blocks);
+ }
+
+ 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) {
+ childIndent = Indent.getNormalIndent();
+ }
+ return new RestBlock(this, child, childAlignment, childIndent, wrap);
+ }
+
+
+ @Nullable
+ @Override
+ public Wrap getWrap() {
+ return myWrap;
+ }
+
+ @Nullable
+ @Override
+ public Indent getIndent() {
+ return myIndent;
+ }
+
+ @Nullable
+ @Override
+ public Alignment getAlignment() {
+ return myAlignment;
+ }
+
+ @Nullable
+ @Override
+ public Spacing getSpacing(@Nullable Block child1, @NotNull Block child2) {
+ return null;
+ }
+
+ @NotNull
+ @Override
+ public ChildAttributes getChildAttributes(int newChildIndex) {
+ return new ChildAttributes(Indent.getNoneIndent(), null);
+ }
+
+ @Override
+ public boolean isIncomplete() {
+ return false;
+ }
+
+ @Override
+ public boolean isLeaf() {
+ return myNode.getFirstChildNode() == null;
+ }
+}
diff --git a/python/rest/src/com/jetbrains/rest/formatter/RestFormattingModelBuilder.java b/python/rest/src/com/jetbrains/rest/formatter/RestFormattingModelBuilder.java
new file mode 100644
index 000000000000..71edb50acb0d
--- /dev/null
+++ b/python/rest/src/com/jetbrains/rest/formatter/RestFormattingModelBuilder.java
@@ -0,0 +1,48 @@
+package com.jetbrains.rest.formatter;
+
+import com.intellij.formatting.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.jetbrains.rest.RestLanguage;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * User : ktisha
+ */
+@SuppressWarnings("UseOfSystemOutOrSystemErr")
+public class RestFormattingModelBuilder implements FormattingModelBuilderEx, CustomFormattingModelBuilder {
+
+ @Override
+ public boolean isEngagedToFormat(PsiElement context) {
+ PsiFile file = context.getContainingFile();
+ return file != null && file.getLanguage() == RestLanguage.INSTANCE;
+ }
+
+ @NotNull
+ @Override
+ public FormattingModel createModel(@NotNull PsiElement element,
+ @NotNull CodeStyleSettings settings,
+ @NotNull FormattingMode mode) {
+
+ final RestBlock block = new RestBlock(null, element.getNode(), null, Indent.getNoneIndent(), null);
+ return FormattingModelProvider.createFormattingModelForPsiFile(element.getContainingFile(), block, settings);
+ }
+
+ @NotNull
+ @Override
+ public FormattingModel createModel(PsiElement element, CodeStyleSettings settings) {
+ return createModel(element, settings, FormattingMode.REFORMAT);
+ }
+
+ @Nullable
+ @Override
+ public TextRange getRangeAffectingIndent(PsiFile file, int offset, ASTNode elementAtOffset) {
+ final PsiElement element = elementAtOffset.getPsi();
+ final PsiElement container = element.getParent();
+ return container != null ? container.getTextRange() : null;
+ }
+}
diff --git a/python/rest/src/com/jetbrains/rest/parsing/RestParser.java b/python/rest/src/com/jetbrains/rest/parsing/RestParser.java
index 00ef744bdde4..e06155c0a4fc 100644
--- a/python/rest/src/com/jetbrains/rest/parsing/RestParser.java
+++ b/python/rest/src/com/jetbrains/rest/parsing/RestParser.java
@@ -47,9 +47,7 @@ public class RestParser implements PsiParser {
marker.done(RestTokenTypes.TITLE);
}
else if (type == RestTokenTypes.FIELD) {
- PsiBuilder.Marker marker = builder.mark();
- builder.advanceLexer();
- marker.done(RestTokenTypes.FIELD);
+ parseFieldList(builder);
}
else if (type == RestTokenTypes.INLINE_LINE) {
PsiBuilder.Marker marker = builder.mark();
@@ -62,13 +60,7 @@ public class RestParser implements PsiParser {
marker.done(RestElementTypes.REFERENCE_TARGET);
}
else if (type == RestTokenTypes.LINE) {
- PsiBuilder.Marker marker = builder.mark();
- while (type == RestTokenTypes.LINE || type == RestTokenTypes.WHITESPACE) {
- builder.advanceLexer();
- type = builder.getTokenType();
- }
-
- marker.done(RestElementTypes.LINE_TEXT);
+ parseLineText(builder, type);
}
else
builder.advanceLexer();
@@ -77,6 +69,32 @@ public class RestParser implements PsiParser {
return builder.getTreeBuilt();
}
+ private static boolean parseLineText(PsiBuilder builder, IElementType type) {
+ PsiBuilder.Marker marker = builder.mark();
+ boolean gotLine = false;
+ while (type == RestTokenTypes.LINE || type == RestTokenTypes.WHITESPACE) {
+ builder.advanceLexer();
+ type = builder.getTokenType();
+ gotLine = true;
+ }
+ if (gotLine)
+ marker.done(RestElementTypes.LINE_TEXT);
+ else
+ marker.drop();
+ return gotLine;
+ }
+
+ private static void parseFieldList(PsiBuilder builder) {
+ PsiBuilder.Marker listMarker = builder.mark();
+ PsiBuilder.Marker marker = builder.mark();
+ builder.advanceLexer();
+ marker.done(RestTokenTypes.FIELD);
+ if (parseLineText(builder, builder.getTokenType()))
+ listMarker.done(RestElementTypes.FIELD_LIST);
+ else
+ listMarker.drop();
+ }
+
private void parseMarkup(PsiBuilder builder) {
PsiBuilder.Marker marker = builder.mark();
IElementType type = builder.getTokenType();
diff --git a/python/rest/src/com/jetbrains/rest/psi/RestASTFactory.java b/python/rest/src/com/jetbrains/rest/psi/RestASTFactory.java
index 6e7f15f314f4..6490751365c7 100644
--- a/python/rest/src/com/jetbrains/rest/psi/RestASTFactory.java
+++ b/python/rest/src/com/jetbrains/rest/psi/RestASTFactory.java
@@ -30,6 +30,9 @@ public class RestASTFactory implements RestTokenTypes, RestElementTypes {
if (type == FIELD) {
return new RestRole(node);
}
+ if (type == FIELD_LIST) {
+ return new RestFieldList(node);
+ }
if (type == INLINE_BLOCK) {
return new RestInlineBlock(node);
}
diff --git a/python/rest/src/com/jetbrains/rest/psi/RestFieldList.java b/python/rest/src/com/jetbrains/rest/psi/RestFieldList.java
new file mode 100644
index 000000000000..d08696270691
--- /dev/null
+++ b/python/rest/src/com/jetbrains/rest/psi/RestFieldList.java
@@ -0,0 +1,19 @@
+package com.jetbrains.rest.psi;
+
+import com.intellij.lang.ASTNode;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * User : ktisha
+ */
+public class RestFieldList extends RestElement {
+ public RestFieldList(@NotNull final ASTNode node) {
+ super(node);
+ }
+
+ @Override
+ public String toString() {
+ return "RestFieldList:" + getNode().getElementType().toString();
+ }
+
+}
diff --git a/python/src/com/jetbrains/python/documentation/doctest/PyDocReference.java b/python/src/com/jetbrains/python/documentation/doctest/PyDocReference.java
index 15a84c184d64..b61ada150c62 100644
--- a/python/src/com/jetbrains/python/documentation/doctest/PyDocReference.java
+++ b/python/src/com/jetbrains/python/documentation/doctest/PyDocReference.java
@@ -11,7 +11,6 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiLanguageInjectionHost;
import com.intellij.psi.ResolveResult;
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
-import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
import com.jetbrains.python.psi.PyQualifiedExpression;
import com.jetbrains.python.psi.impl.references.PyReferenceImpl;
import com.jetbrains.python.psi.resolve.*;
@@ -63,8 +62,8 @@ public class PyDocReference extends PyReferenceImpl {
ResolveProcessor processor = new ResolveProcessor(referencedName);
- final ScopeOwner scopeOwner = ScopeUtil.getScopeOwner(myElement);
- PyResolveUtil.scopeCrawlUp(processor, scopeOwner != null? scopeOwner : (ScopeOwner)file, referencedName, file);
+ if (file instanceof ScopeOwner)
+ PyResolveUtil.scopeCrawlUp(processor, (ScopeOwner)file, referencedName, file);
final List resultList = getResultsFromProcessor(referencedName, processor, file, file);
if (resultList.size() > 0)
return resultList.toArray(new RatedResolveResult[resultList.size()]);
@@ -86,7 +85,8 @@ public class PyDocReference extends PyReferenceImpl {
// include our own names
final CompletionVariantsProcessor processor = new CompletionVariantsProcessor(element);
- PyResolveUtil.scopeCrawlUp(processor, (ScopeOwner)file, null, null);
+ if (file instanceof ScopeOwner)
+ PyResolveUtil.scopeCrawlUp(processor, (ScopeOwner)file, null, null);
ret.addAll(processor.getResultList());