Merge branch 'master' of git@git.labs.intellij.net:idea/community

This commit is contained in:
Kirill Kalishev
2010-05-20 16:13:31 +04:00
29 changed files with 422 additions and 329 deletions
@@ -30,6 +30,7 @@ public class JavaIndentOptionsEditor extends SmartIndentOptionsEditor {
private JCheckBox myLabelIndentAbsolute;
private JCheckBox myCbDontIndentTopLevelMembers;
private JCheckBox myCbUseRelativeIndent;
protected void addComponents() {
super.addComponents();
@@ -42,6 +43,9 @@ public class JavaIndentOptionsEditor extends SmartIndentOptionsEditor {
myCbDontIndentTopLevelMembers = new JCheckBox(ApplicationBundle.message("checkbox.do.not.indent.top.level.class.members"));
add(myCbDontIndentTopLevelMembers);
myCbUseRelativeIndent = new JCheckBox(ApplicationBundle.message("checkbox.use.relative.indents"));
add(myCbUseRelativeIndent);
}
public boolean isModified(final CodeStyleSettings settings, final CodeStyleSettings.IndentOptions options) {
@@ -50,6 +54,7 @@ public class JavaIndentOptionsEditor extends SmartIndentOptionsEditor {
isModified |= isFieldModified(myLabelIndent, options.LABEL_INDENT_SIZE);
isModified |= isFieldModified(myLabelIndentAbsolute, options.LABEL_INDENT_ABSOLUTE);
isModified |= isFieldModified(myCbDontIndentTopLevelMembers, settings.DO_NOT_INDENT_TOP_LEVEL_CLASS_MEMBERS);
isModified |= isFieldModified(myCbUseRelativeIndent, options.USE_RELATIVE_INDENTS);
return isModified;
}
@@ -64,6 +69,7 @@ public class JavaIndentOptionsEditor extends SmartIndentOptionsEditor {
}
options.LABEL_INDENT_ABSOLUTE = myLabelIndentAbsolute.isSelected();
settings.DO_NOT_INDENT_TOP_LEVEL_CLASS_MEMBERS = myCbDontIndentTopLevelMembers.isSelected();
options.USE_RELATIVE_INDENTS = myCbUseRelativeIndent.isSelected();
}
public void reset(@NotNull final CodeStyleSettings settings, @NotNull final CodeStyleSettings.IndentOptions options) {
@@ -71,6 +77,7 @@ public class JavaIndentOptionsEditor extends SmartIndentOptionsEditor {
myLabelIndent.setText(Integer.toString(options.LABEL_INDENT_SIZE));
myLabelIndentAbsolute.setSelected(options.LABEL_INDENT_ABSOLUTE);
myCbDontIndentTopLevelMembers.setSelected(settings.DO_NOT_INDENT_TOP_LEVEL_CLASS_MEMBERS);
myCbUseRelativeIndent.setSelected(options.USE_RELATIVE_INDENTS);
}
public void setEnabled(final boolean enabled) {
@@ -154,6 +154,9 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor {
@Override
protected void reformat(PsiElement atCaret) throws IncorrectOperationException {
if (atCaret == null) {
return;
}
PsiElement parent = atCaret.getParent();
if (parent instanceof PsiCodeBlock) {
final PsiCodeBlock block = (PsiCodeBlock) parent;
@@ -430,22 +430,26 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
return buffer.toString();
}
public PsiComment findExistingDocComment(final PsiComment _element) {
PsiElement parentElement = _element.getParent();
return parentElement instanceof PsiDocCommentOwner ? ((PsiDocCommentOwner)parentElement).getDocComment() : null;
public PsiComment findExistingDocComment(final PsiComment comment) {
if (comment instanceof PsiDocComment) {
final PsiDocCommentOwner owner = ((PsiDocComment)comment).getOwner();
if (owner != null) {
return owner.getDocComment();
}
}
return null;
}
public String generateDocumentationContentStub(PsiComment _element) {
PsiElement parentElement = _element.getParent();
final Project project = _element.getProject();
public String generateDocumentationContentStub(PsiComment _comment) {
final PsiDocCommentOwner commentOwner = ((PsiDocComment)_comment).getOwner();
final Project project = commentOwner.getProject();
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
if (parentElement instanceof PsiMethod) {
PsiMethod psiMethod = (PsiMethod)parentElement;
final CodeDocumentationAwareCommenter commenter = (CodeDocumentationAwareCommenter)LanguageCommenters.INSTANCE
.forLanguage(commentOwner.getLanguage());
if (commentOwner instanceof PsiMethod) {
PsiMethod psiMethod = (PsiMethod)commentOwner;
final PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
final CodeDocumentationAwareCommenter commenter = (CodeDocumentationAwareCommenter)LanguageCommenters.INSTANCE
.forLanguage(parentElement.getLanguage());
final Map<String, String> param2Description = new HashMap<String, String>();
final PsiMethod[] superMethods = psiMethod.findSuperMethods();
for (PsiMethod superMethod : superMethods) {
@@ -499,11 +503,9 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
builder.append(LINE_SEPARATOR);
}
}
else if (parentElement instanceof PsiClass) {
final PsiTypeParameterList typeParameterList = ((PsiClass)parentElement).getTypeParameterList();
else if (commentOwner instanceof PsiClass) {
final PsiTypeParameterList typeParameterList = ((PsiClass)commentOwner).getTypeParameterList();
if (typeParameterList != null) {
final CodeDocumentationAwareCommenter commenter = (CodeDocumentationAwareCommenter)LanguageCommenters.INSTANCE
.forLanguage(parentElement.getLanguage());
createTypeParamsListComment(builder, project, commenter, typeParameterList);
}
}
@@ -213,6 +213,10 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
}
}
protected static boolean isRBrace(final ASTNode child) {
return child.getElementType() == ElementType.RBRACE;
}
public Spacing getSpacing(Block child1, Block child2) {
return JavaSpacePropertyProcessor.getSpacing(getTreeNode(child2), mySettings);
}
@@ -1080,4 +1084,32 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
return JavaBlockUtil.mayShiftIndentInside(myNode);
}
@Nullable
protected ASTNode composeCodeBlock(final ArrayList<Block> result, ASTNode child, final Indent indent, final int childrenIndent) {
final ArrayList<Block> localResult = new ArrayList<Block>();
processChild(localResult, child, null, null, Indent.getNoneIndent());
child = child.getTreeNext();
while (child != null) {
if (!FormatterUtil.containsWhiteSpacesOnly(child)) {
final boolean rBrace = isRBrace(child);
final Indent childIndent = rBrace ? Indent.getNoneIndent() : getCodeBlockInternalIndent(childrenIndent);
child = processChild(localResult, child, null, null, childIndent);
if (rBrace) {
result.add(createCodeBlockBlock(localResult, indent, childrenIndent));
return child;
}
}
if (child != null) {
child = child.getTreeNext();
}
}
result.add(createCodeBlockBlock(localResult, indent, childrenIndent));
return null;
}
private SyntheticCodeBlock createCodeBlockBlock(final ArrayList<Block> localResult, final Indent indent, final int childrenIndent) {
final SyntheticCodeBlock result = new SyntheticCodeBlock(localResult, null, getSettings(), indent, null);
result.setChildAttributes(new ChildAttributes(getCodeBlockInternalIndent(childrenIndent), null));
return result;
}
}
@@ -17,6 +17,7 @@ package com.intellij.psi.formatter.java;
import com.intellij.formatting.*;
import com.intellij.lang.ASTNode;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.formatter.FormatterUtil;
import com.intellij.psi.impl.source.tree.ElementType;
@@ -52,6 +53,7 @@ public class BlockContainingJavaBlock extends AbstractJavaBlock{
private void buildChildren(final ArrayList<Block> result, final Alignment childAlignment, final Wrap childWrap) {
ASTNode child = myNode.getFirstChildNode();
ASTNode prevChild = null;
int state = BEFORE_FIRST;
@@ -60,7 +62,26 @@ public class BlockContainingJavaBlock extends AbstractJavaBlock{
final Indent indent = calcIndent(child, state);
myIndentsBefore.add(calcIndentBefore(child, state));
state = calcNewState(child, state);
child = processChild(result, child, childAlignment, childWrap, indent);
// The general idea is that it's possible that there are comment lines before method declaration line and that they have
// different indents. Example:
//
// // This is comment before method
// void foo() {}
//
// We want to have the comment and method as distinct blocks then in order to correctly process indentation for inner method
// elements. See IDEA-53778 for example of situation when it is significant.
if (prevChild != null && myNode.getElementType() == ElementType.METHOD
&& JavaTokenType.COMMENT_BIT_SET.contains(prevChild.getElementType())
&& !JavaTokenType.COMMENT_BIT_SET.contains(child.getElementType()))
{
prevChild = child;
child = composeCodeBlock(result, child, Indent.getNoneIndent(), 0);
}
else {
prevChild = child;
child = processChild(result, child, childAlignment, childWrap, indent);
}
for (int i = myIndentsBefore.size(); i < result.size(); i++) {
myIndentsBefore.add(Indent.getContinuationIndent());
}
@@ -86,7 +86,7 @@ public class CodeBlockBlock extends AbstractJavaBlock {
child = processCaseAndStatementAfter(result, child, childAlignment, childWrap, indent);
}
else if (myNode.getElementType() == ElementType.CLASS && child.getElementType() == ElementType.LBRACE) {
child = composeCodeBlock(result, child, getCodeBlockExternalIndent());
child = composeCodeBlock(result, child, getCodeBlockExternalIndent(), myChildrenIndent);
}
else {
child = processChild(result, child, childAlignment, childWrap, indent);
@@ -98,35 +98,6 @@ public class CodeBlockBlock extends AbstractJavaBlock {
}
}
@Nullable
private ASTNode composeCodeBlock(final ArrayList<Block> result, ASTNode child, final Indent indent) {
final ArrayList<Block> localResult = new ArrayList<Block>();
processChild(localResult, child, null, null, Indent.getNoneIndent());
child = child.getTreeNext();
while (child != null) {
if (!FormatterUtil.containsWhiteSpacesOnly(child)) {
final boolean rBrace = isRBrace(child);
final Indent childIndent = rBrace ? Indent.getNoneIndent() : getCodeBlockInternalIndent(myChildrenIndent);
child = processChild(localResult, child, null, null, childIndent);
if (rBrace) {
result.add(createCodeBlockBlock(localResult, indent));
return child;
}
}
if (child != null) {
child = child.getTreeNext();
}
}
result.add(createCodeBlockBlock(localResult, indent));
return null;
}
private SyntheticCodeBlock createCodeBlockBlock(final ArrayList<Block> localResult, final Indent indent) {
final SyntheticCodeBlock result = new SyntheticCodeBlock(localResult, null, getSettings(), indent, null);
result.setChildAttributes(new ChildAttributes(getCodeBlockInternalIndent(myChildrenIndent), null));
return result;
}
@Nullable
private ASTNode processCaseAndStatementAfter(final ArrayList<Block> result,
ASTNode child,
@@ -253,10 +224,6 @@ public class CodeBlockBlock extends AbstractJavaBlock {
}
}
private static boolean isRBrace(final ASTNode child) {
return child.getElementType() == ElementType.RBRACE;
}
@Override
@NotNull
public ChildAttributes getChildAttributes(final int newChildIndex) {
@@ -15,7 +15,6 @@
*/
package com.intellij.psi.impl.compiled;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.JavaDocElementType;
import com.intellij.psi.impl.source.tree.TreeElement;
@@ -26,12 +25,10 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
class ClsDocCommentImpl extends ClsElementImpl implements PsiDocComment, JavaTokenType, PsiJavaToken {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsDocCommentImpl");
private final ClsElementImpl myParent;
private final PsiDocCommentOwner myParent;
private final PsiDocTag[] myTags;
ClsDocCommentImpl(ClsElementImpl parent) {
ClsDocCommentImpl(PsiDocCommentOwner parent) {
myParent = parent;
PsiDocTag[] tags = new PsiDocTag[1];
@@ -63,10 +60,16 @@ class ClsDocCommentImpl extends ClsElementImpl implements PsiDocComment, JavaTok
return myParent;
}
public PsiDocCommentOwner getOwner() {
return myParent;
}
@NotNull
public PsiElement[] getDescriptionElements() {
return EMPTY_ARRAY;
}
@NotNull
public PsiDocTag[] getTags() {
return myTags;
}
@@ -76,6 +79,7 @@ class ClsDocCommentImpl extends ClsElementImpl implements PsiDocComment, JavaTok
return getTags()[0];
}
@NotNull
public PsiDocTag[] findTagsByName(@NonNls String name) {
if (!name.equals("deprecated")) return PsiDocTag.EMPTY_ARRAY;
return getTags();
@@ -18,10 +18,7 @@ package com.intellij.psi.impl.source.javadoc;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaElementVisitor;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.impl.source.Constants;
import com.intellij.psi.impl.source.PsiElementArrayConstructor;
@@ -57,18 +54,32 @@ public class PsiDocCommentImpl extends LazyParseablePsiElement implements PsiDoc
super(JavaDocElementType.DOC_COMMENT, text);
}
public PsiDocCommentOwner getOwner() {
final PsiElement parent = getParent();
if (parent instanceof PsiDocCommentOwner) {
final PsiDocCommentOwner owner = (PsiDocCommentOwner)parent;
if (owner.getDocComment() == this) {
return owner;
}
}
return null;
}
@NotNull
public PsiElement[] getDescriptionElements() {
ArrayList<ASTNode> array = new ArrayList<ASTNode>();
ArrayList<PsiElement> array = new ArrayList<PsiElement>();
for (ASTNode child = getFirstChildNode(); child != null; child = child.getTreeNext()) {
IElementType i = child.getElementType();
if (i == DOC_TAG) break;
if (i != DOC_COMMENT_START && i != DOC_COMMENT_END && i != DOC_COMMENT_LEADING_ASTERISKS) {
array.add(child);
array.add(child.getPsi());
}
}
return array.toArray(new PsiElement[array.size()]);
}
@NotNull
public PsiDocTag[] getTags() {
return getChildrenAsPsiElements(TAG_BIT_SET, PSI_TAG_ARRAY_CONSTRUCTOR);
}
@@ -92,6 +103,7 @@ public class PsiDocCommentImpl extends LazyParseablePsiElement implements PsiDoc
return null;
}
@NotNull
public PsiDocTag[] findTagsByName(String name) {
ArrayList<PsiDocTag> array = new ArrayList<PsiDocTag>();
PsiDocTag[] tags = getTags();
@@ -1,7 +1,7 @@
class X {
/**
* Has a method called {@link #mymethod(int,int)}.
* Has a method called {@link #mymethod(int, int)}.
*/
public class TestRefactorLink {
public void <caret>mymethod(int y, int z) { }
@@ -1,7 +1,7 @@
class X {
/**
* Has a method called {@link #mymethod(int,boolean)}.
* Has a method called {@link #mymethod(int, boolean)}.
*/
public class TestRefactorLink {
public void mymethod(int y, boolean b) { }
@@ -22,6 +22,7 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.ex.DocumentEx;
import com.intellij.openapi.editor.impl.DocumentImpl;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
@@ -74,6 +75,10 @@ public abstract class AbstractJavaFormatterTest extends LightIdeaTestCase {
return CodeStyleSettingsManager.getSettings(getProject());
}
public static CodeStyleSettings.IndentOptions getIndentOptions() {
return getSettings().getIndentOptions(StdFileTypes.JAVA);
}
public void doTest() throws Exception {
doTest(getTestName(false) + ".java", getTestName(false) + "_after.java");
}
@@ -173,34 +173,103 @@ public class JavaFormatterIndentationTest extends AbstractJavaFormatterTest {
public void testCaseFromSwitch() throws IncorrectOperationException {
// Inspired by IDEADEV-22920
getSettings().INDENT_CASE_FROM_SWITCH = false;
doTextTest("class Foo{\n" +
"void foo () {\n" +
"switch(someValue) {\n" +
" // This comment is correctly not-indented\n" +
" case 1:\n" +
" doSomething();\n" +
" break;\n" +
"\n" +
" // This comment should not be indented, but it is\n" +
" case 2:\n" +
" doSomethingElse();\n" +
" break;\n" +
"}\n" +
"}\n" +
"}", "class Foo {\n" +
" void foo() {\n" +
" switch (someValue) {\n" +
" // This comment is correctly not-indented\n" +
" case 1:\n" +
" doSomething();\n" +
" break;\n" +
"\n" +
" // This comment should not be indented, but it is\n" +
" case 2:\n" +
" doSomethingElse();\n" +
" break;\n" +
" }\n" +
" }\n" +
"}");
doTextTest(
"class Foo{\n" +
"void foo () {\n" +
"switch(someValue) {\n" +
" // This comment is correctly not-indented\n" +
" case 1:\n" +
" doSomething();\n" +
" break;\n" +
"\n" +
" // This comment should not be indented, but it is\n" +
" case 2:\n" +
" doSomethingElse();\n" +
" break;\n" +
"}\n" +
"}\n" +
"}",
"class Foo {\n" +
" void foo() {\n" +
" switch (someValue) {\n" +
" // This comment is correctly not-indented\n" +
" case 1:\n" +
" doSomething();\n" +
" break;\n" +
"\n" +
" // This comment should not be indented, but it is\n" +
" case 2:\n" +
" doSomethingElse();\n" +
" break;\n" +
" }\n" +
" }\n" +
"}");
}
public void testBinaryExpressionsWithRelativeIndents() {
// Inspired by IDEA-21795
getIndentOptions().USE_RELATIVE_INDENTS = true;
getIndentOptions().CONTINUATION_INDENT_SIZE = 4;
doTextTest(
"public class FormattingTest {\n" +
"\n" +
" public boolean test1(int a, int b, int c, int d) {\n" +
" return a == 1 &&\n" +
" b == 2;\n" +
" }\n" +
"\n" +
" public boolean multilineSignOnCurrent(int a, int b, int c, int d) {\n" +
" return a == 0 &&\n" +
" (b == 0 ||\n" +
" c == 0) &&\n" +
" d == 0;\n" +
" }\n" +
"\n" +
" public boolean multilineSignOnNext(int a, int b, int c, int d) {\n" +
" return a == 0\n" +
" && (b == 0\n" +
" || c == 0)\n" +
" && d == 0;\n" +
" }\n" +
"\n" +
" public boolean expectedMultilineSignOnNext(int a, int b, int c, int d) {\n" +
" return a == 0\n" +
" && (b == 0\n" +
" || c == 0)\n" +
" && d == 0;\n" +
" }\n" +
"}",
"public class FormattingTest {\n" +
"\n" +
" public boolean test1(int a, int b, int c, int d) {\n" +
" return a == 1 &&\n" +
" b == 2;\n" +
" }\n" +
"\n" +
" public boolean multilineSignOnCurrent(int a, int b, int c, int d) {\n" +
" return a == 0 &&\n" +
" (b == 0 ||\n" +
" c == 0) &&\n" +
" d == 0;\n" +
" }\n" +
"\n" +
" public boolean multilineSignOnNext(int a, int b, int c, int d) {\n" +
" return a == 0\n" +
" && (b == 0\n" +
" || c == 0)\n" +
" && d == 0;\n" +
" }\n" +
"\n" +
" public boolean expectedMultilineSignOnNext(int a, int b, int c, int d) {\n" +
" return a == 0\n" +
" && (b == 0\n" +
" || c == 0)\n" +
" && d == 0;\n" +
" }\n" +
"}"
);
}
}
@@ -22,7 +22,9 @@ import com.intellij.util.IncorrectOperationException;
* @author Denis Zhdanov
* @since May 11, 2010 5:30:28 PM
*/
public class AutoIndentLinesTest extends AbstractJavaFormatterTest {
public class JavaIndenterTest extends AbstractJavaFormatterTest {
private static final String CARET_TOKEN = "<caret>";
public void testIndentAlignedMethodParameter() {
// Inspired by IDEA-22020
@@ -41,7 +43,7 @@ public class AutoIndentLinesTest extends AbstractJavaFormatterTest {
int end = initial.indexOf("\n", start);
myTextRange = new TextRange(start, end);
doTextTest(Action.INDENT, initial,
doTextTest(initial,
"class BrokenAlignment {\n" +
" public\n" +
"\tstatic int foo(String a, String b, String c,\n" +
@@ -52,8 +54,41 @@ public class AutoIndentLinesTest extends AbstractJavaFormatterTest {
);
}
public void testMethodBodyShiftedToComment() {
// Inspired by IDEA-53778
doTextTest(
"class Test {\n" +
" // some comment\n" +
" public void doSmth(int[] p) {\n" +
"<caret>\n" +
" }" +
"}",
"class Test {\n" +
" // some comment\n" +
" public void doSmth(int[] p) {\n" +
" \n" +
" }" +
"}");
}
@Override
public void doTextTest(String text, String textAfter) throws IncorrectOperationException {
doTextTest(Action.INDENT, text, textAfter);
doTextTest(Action.INDENT, adjustTextIfNecessary(text), textAfter);
}
private String adjustTextIfNecessary(String text) {
int caretIndex = text.indexOf(CARET_TOKEN);
if (caretIndex < 0) {
return text;
}
if (caretIndex < text.length() && text.indexOf(CARET_TOKEN, caretIndex + 1) >= 0) {
fail(String.format("Invalid indentation test 'before' text - it contains more than one caret meta-token (%s). Text: %n%s",
CARET_TOKEN, text));
}
myTextRange = new TextRange(caretIndex, caretIndex);
return text.substring(0, caretIndex) + text.substring(caretIndex + CARET_TOKEN.length());
}
}
@@ -40,8 +40,6 @@ import java.util.Set;
*/
public abstract class JspManager implements IBaseJspManager {
public static final Key<VirtualFile[]> DIRECTORIES_KEY = Key.create("TagDirOriginalDirs");
public static JspManager getInstance(@NotNull Project project) {
return ServiceManager.getService(project, JspManager.class);
}
@@ -16,13 +16,25 @@
package com.intellij.psi.javadoc;
import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiDocCommentOwner;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface PsiDocComment extends PsiComment {
@Nullable
PsiDocCommentOwner getOwner();
@NotNull
PsiElement[] getDescriptionElements();
@NotNull
PsiDocTag[] getTags();
@Nullable
PsiDocTag findTagByName(@NonNls String name);
@NotNull
PsiDocTag[] findTagsByName(@NonNls String name);
}
@@ -199,6 +199,7 @@ public class CodeStyleSettings implements Cloneable, JDOMExternalizable {
public boolean SMART_TABS = false;
public int LABEL_INDENT_SIZE = 0;
public boolean LABEL_INDENT_ABSOLUTE = false;
public boolean USE_RELATIVE_INDENTS = false;
public void readExternal(Element element) throws InvalidDataException {
DefaultJDOMExternalizer.readExternal(this, element);
@@ -228,6 +229,7 @@ public class CodeStyleSettings implements Cloneable, JDOMExternalizable {
if (CONTINUATION_INDENT_SIZE != that.CONTINUATION_INDENT_SIZE) return false;
if (INDENT_SIZE != that.INDENT_SIZE) return false;
if (LABEL_INDENT_ABSOLUTE != that.LABEL_INDENT_ABSOLUTE) return false;
if (USE_RELATIVE_INDENTS != that.USE_RELATIVE_INDENTS) return false;
if (LABEL_INDENT_SIZE != that.LABEL_INDENT_SIZE) return false;
if (SMART_TABS != that.SMART_TABS) return false;
if (TAB_SIZE != that.TAB_SIZE) return false;
@@ -245,6 +247,7 @@ public class CodeStyleSettings implements Cloneable, JDOMExternalizable {
result = 31 * result + (SMART_TABS ? 1 : 0);
result = 31 * result + LABEL_INDENT_SIZE;
result = 31 * result + (LABEL_INDENT_ABSOLUTE ? 1 : 0);
result = 31 * result + (USE_RELATIVE_INDENTS ? 1 : 0);
return result;
}
@@ -15,27 +15,14 @@
*/
package com.intellij.application.options.codeStyle;
import com.intellij.application.options.CodeStyleAbstractPanel;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.containers.HashMap;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.tree.*;
@@ -46,7 +33,6 @@ import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
/**
* @author max
@@ -54,8 +40,8 @@ import java.util.Arrays;
public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleAbstractPanel {
private static final Logger LOG = Logger.getInstance("#com.intellij.application.options.CodeStyleSpacesPanel");
private final JTree myOptionsTree;
private final HashMap myKeyToFieldMap = new HashMap();
private final ArrayList myKeys = new ArrayList();
private final HashMap<BooleanOptionKey, Field> myKeyToFieldMap = new HashMap<BooleanOptionKey, Field>();
private final ArrayList<BooleanOptionKey> myKeys = new ArrayList<BooleanOptionKey>();
private final JPanel myPanel = new JPanel(new GridBagLayout());
public OptionTreeWithPreviewPanel(CodeStyleSettings settings) {
@@ -84,32 +70,14 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
String groupName = "";
DefaultMutableTreeNode groupNode = null;
for (int i = 0; i < myKeys.size(); i++) {
if (myKeys.get(i) instanceof BooleanOptionKey) {
BooleanOptionKey key = (BooleanOptionKey)myKeys.get(i);
String newGroupName = key.groupName;
if (!newGroupName.equals(groupName) || groupNode == null) {
groupName = newGroupName;
groupNode = new DefaultMutableTreeNode(newGroupName);
rootNode.add(groupNode);
}
groupNode.add(new MyToggleTreeNode(key, key.cbName));
}
else if (myKeys.get(i) instanceof IntSelectionOptionKey) {
IntSelectionOptionKey key = (IntSelectionOptionKey)myKeys.get(i);
String newGroupName = key.groupName;
if (!newGroupName.equals(groupName) || groupNode == null) {
groupName = newGroupName;
groupNode = new DefaultMutableTreeNode(newGroupName);
rootNode.add(groupNode);
}
MyToggleTreeNode[] nodes = new MyToggleTreeNode[key.rbNames.length];
for (int j = 0; j < nodes.length; j++) {
nodes[j] = new MyToggleTreeNode(key, key.rbNames[j]);
groupNode.add(nodes[j]);
}
key.setCreatedNodes(nodes);
for (BooleanOptionKey key: myKeys) {
String newGroupName = key.groupName;
if (!newGroupName.equals(groupName) || groupNode == null) {
groupName = newGroupName;
groupNode = new DefaultMutableTreeNode(newGroupName);
rootNode.add(groupNode);
}
groupNode.add(new MyToggleTreeNode(key, key.cbName));
}
DefaultTreeModel model = new DefaultTreeModel(rootNode);
@@ -156,19 +124,7 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
Object o = treePath.getLastPathComponent();
if (o instanceof MyToggleTreeNode) {
MyToggleTreeNode node = (MyToggleTreeNode)o;
if (node.isCheckbox()) {
node.setSelected(!node.isSelected());
}
else {
MyToggleTreeNode[] group = node.getGroup();
for (int i = 0; i < group.length; i++) {
MyToggleTreeNode groupNode = group[i];
groupNode.setSelected(false);
int row = myOptionsTree.getRowForPath(new TreePath(groupNode.getPath()));
myOptionsTree.repaint(myOptionsTree.getRowBounds(row));
}
node.setSelected(true);
}
node.setSelected(!node.isSelected());
int row = myOptionsTree.getRowForPath(treePath);
myOptionsTree.repaint(myOptionsTree.getRowBounds(row));
//updatePreview();
@@ -201,21 +157,9 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
private void resetMyTreeNode(MyToggleTreeNode childNode, final CodeStyleSettings settings) {
try {
if (childNode.getKey() instanceof BooleanOptionKey) {
BooleanOptionKey key = (BooleanOptionKey)childNode.getKey();
Field field = (Field)myKeyToFieldMap.get(key);
childNode.setSelected(field.getBoolean(settings));
}
else if (childNode.getKey() instanceof IntSelectionOptionKey) {
IntSelectionOptionKey key = (IntSelectionOptionKey)childNode.getKey();
Field field = (Field)myKeyToFieldMap.get(key);
int fieldValue = field.getInt(settings);
for (int i = 0; i < key.rbNames.length; i++) {
if (childNode.getText().equals(key.rbNames[i])) {
childNode.setSelected(fieldValue == key.values[i]);
}
}
}
BooleanOptionKey key = (BooleanOptionKey)childNode.getKey();
Field field = myKeyToFieldMap.get(key);
childNode.setSelected(field.getBoolean(settings));
}
catch (IllegalArgumentException e) {
LOG.error(e);
@@ -244,22 +188,9 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
private void applyToggleNode(MyToggleTreeNode childNode, final CodeStyleSettings settings) {
try {
if (childNode.getKey() instanceof BooleanOptionKey) {
BooleanOptionKey key = (BooleanOptionKey)childNode.getKey();
Field field = (Field)myKeyToFieldMap.get(key);
field.set(settings, childNode.isSelected() ? Boolean.TRUE : Boolean.FALSE);
}
else if (childNode.getKey() instanceof IntSelectionOptionKey) {
if (!childNode.isSelected()) return;
IntSelectionOptionKey key = (IntSelectionOptionKey)childNode.getKey();
Field field = (Field)myKeyToFieldMap.get(key);
for (int i = 0; i < key.rbNames.length; i++) {
if (childNode.getText().equals(key.rbNames[i])) {
field.set(settings, new Integer(key.values[i]));
break;
}
}
}
BooleanOptionKey key = (BooleanOptionKey)childNode.getKey();
Field field = myKeyToFieldMap.get(key);
field.set(settings, childNode.isSelected() ? Boolean.TRUE : Boolean.FALSE);
}
catch (IllegalArgumentException e) {
LOG.error(e);
@@ -296,21 +227,9 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
private boolean isToggleNodeModified(MyToggleTreeNode childNode, final CodeStyleSettings settings) {
try {
if (childNode.getKey() instanceof BooleanOptionKey) {
BooleanOptionKey key = (BooleanOptionKey)childNode.getKey();
Field field = (Field)myKeyToFieldMap.get(key);
return childNode.isSelected() != field.getBoolean(settings);
}
else if (childNode.getKey() instanceof IntSelectionOptionKey) {
if (!childNode.isSelected()) return false;
IntSelectionOptionKey key = (IntSelectionOptionKey)childNode.getKey();
Field field = (Field)myKeyToFieldMap.get(key);
for (int i = 0; i < key.rbNames.length; i++) {
if (childNode.getText().equals(key.rbNames[i])) {
return field.getInt(settings) != key.values[i];
}
}
}
BooleanOptionKey key = (BooleanOptionKey)childNode.getKey();
Field field = myKeyToFieldMap.get(key);
return childNode.isSelected() != field.getBoolean(settings);
}
catch (IllegalArgumentException e) {
LOG.error(e);
@@ -335,20 +254,6 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
}
}
protected void initRadioGroupField(String fieldName, String groupName, String[] rbNames, int[] values) {
try {
Class styleSettingsClass = CodeStyleSettings.class;
Field field = styleSettingsClass.getField(fieldName);
IntSelectionOptionKey key = new IntSelectionOptionKey(groupName, rbNames, values);
myKeyToFieldMap.put(key, field);
myKeys.add(key);
}
catch (NoSuchFieldException e) {
}
catch (SecurityException e) {
}
}
protected void prepareForReformat(final PsiFile psiFile) {
//psiFile.putUserData(PsiUtil.FILE_LANGUAGE_LEVEL_KEY, LanguageLevel.HIGHEST);
}
@@ -356,12 +261,10 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
protected class MyTreeCellRenderer implements TreeCellRenderer {
private final MyLabelPanel myLabel;
private final JCheckBox myCheckBox;
private final JRadioButton myRadioButton;
public MyTreeCellRenderer() {
myLabel = new MyLabelPanel();
myCheckBox = new JCheckBox();
myRadioButton = new JRadioButton();
myCheckBox.setMargin(new Insets(0, 0, 0, 0));
}
@@ -370,7 +273,7 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
if (value instanceof MyToggleTreeNode) {
MyToggleTreeNode treeNode = (MyToggleTreeNode)value;
JToggleButton button = treeNode.isCheckbox() ? (JToggleButton)myCheckBox : (JToggleButton)myRadioButton;
JToggleButton button = myCheckBox;
button.setText(treeNode.getText());
button.setSelected(treeNode.isSelected);
if (isSelected) {
@@ -473,64 +376,23 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA
}
}
private static class IntSelectionOptionKey {
final String groupName;
final String[] rbNames;
final int[] values;
private MyToggleTreeNode[] myNodes;
public IntSelectionOptionKey(String groupName, String[] rbNames, int[] values) {
this.groupName = groupName;
this.rbNames = rbNames;
this.values = values;
}
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof IntSelectionOptionKey)) return false;
final IntSelectionOptionKey intSelectionOptionKey = (IntSelectionOptionKey)o;
if (!groupName.equals(intSelectionOptionKey.groupName)) return false;
if (!Arrays.equals(rbNames, intSelectionOptionKey.rbNames)) return false;
return true;
}
public int hashCode() {
return groupName.hashCode() + rbNames[0].hashCode() * 29;
}
public void setCreatedNodes(MyToggleTreeNode[] nodes) { myNodes = nodes; }
public MyToggleTreeNode[] getNodes() { return myNodes; }
}
private static class MyToggleTreeNode extends DefaultMutableTreeNode {
private final Object myKey;
private final String myText;
private boolean isSelected;
private final boolean isCheckbox;
public MyToggleTreeNode(Object key, String text) {
myKey = key;
myText = text;
isCheckbox = true;
}
public Object getKey() { return myKey; }
public String getText() { return myText; }
public boolean isCheckbox() { return isCheckbox; }
public void setSelected(boolean val) { isSelected = val; }
public boolean isSelected() { return isSelected; }
public MyToggleTreeNode[] getGroup() {
return ((IntSelectionOptionKey)myKey).getNodes();
}
}
public JComponent getInternalPanel() {
@@ -222,6 +222,35 @@ public class CustomTemplateCallback {
myBuilder.insertText(offset, text);
}
public void insertNewLine() {
myBuilder.insertText(myOffset, "\n");
myOffset++;
}
public boolean newLineBefore() {
int i = myOffset - 1;
CharSequence text = myBuilder.getText();
while (i >= 0 && Character.isWhitespace(text.charAt(i))) {
if (text.charAt(i) == '\n') {
return true;
}
i--;
}
return i < 0;
}
public boolean newLineAfter() {
int i = myOffset;
CharSequence text = myBuilder.getText();
while (i < text.length() && Character.isWhitespace(text.charAt(i))) {
if (text.charAt(i) == '\n') {
return true;
}
i++;
}
return i == text.length();
}
public void deleteTemplateKey(String key) {
int caretAt = myEditor.getCaretModel().getOffset();
myEditor.getDocument().deleteString(caretAt - key.length(), caretAt);
@@ -21,11 +21,24 @@ import com.intellij.psi.codeStyle.CodeStyleSettings;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import static java.util.Arrays.asList;
/**
* @author lesya
*/
public abstract class AbstractBlockWrapper {
private static final Set<IndentImpl.Type> RELATIVE_INDENT_TYPES = new HashSet<IndentImpl.Type>(asList(
IndentImpl.Type.NORMAL, IndentImpl.Type.CONTINUATION, IndentImpl.Type.CONTINUATION_WITHOUT_FIRST
));
private static final Set<IndentImpl.Type> CONTINUATION_INDENT_TYPES = new HashSet<IndentImpl.Type>(asList(
IndentImpl.Type.CONTINUATION, IndentImpl.Type.CONTINUATION_WITHOUT_FIRST
));
protected WhiteSpace myWhiteSpace;
protected CompositeBlockWrapper myParent;
protected int myStart;
@@ -154,36 +167,38 @@ public abstract class AbstractBlockWrapper {
}
public IndentData getChildOffset(AbstractBlockWrapper child, CodeStyleSettings.IndentOptions options, final int tokenBlockStartOffset) {
final boolean childOnNewLine = child.getWhiteSpace().containsLineFeeds();
public IndentData getChildOffset(AbstractBlockWrapper child, CodeStyleSettings.IndentOptions options, int targetBlockStartOffset) {
final boolean childStartsNewLine = child.getWhiteSpace().containsLineFeeds();
IndentImpl.Type childIndentType = child.getIndent().getType();
final IndentData childIndent;
// Calculate child indent.
if (childOnNewLine) {
childIndent = getIndent(options, child, tokenBlockStartOffset);
if (childStartsNewLine
|| (!getWhiteSpace().containsLineFeeds() && RELATIVE_INDENT_TYPES.contains(childIndentType) && indentAlreadyUsedBefore(child)))
{
childIndent = getIndent(options, child, targetBlockStartOffset);
}
else {
IndentImpl.Type type = child.getIndent().getType();
if (!getWhiteSpace().containsLineFeeds()
&& (type == IndentImpl.Type.NORMAL || type == IndentImpl.Type.CONTINUATION || type == IndentImpl.Type.CONTINUATION_WITHOUT_FIRST)
&& indentAlreadyUsedBefore(child))
{
childIndent = getIndent(options, child, tokenBlockStartOffset);
}
else {
childIndent = new IndentData(0);
}
childIndent = new IndentData(0);
}
// Use child indent if it's absolute and the child is contained on new line.
if (childOnNewLine && child.getIndent().isAbsolute()) {
myFlags &= ~CAN_USE_FIRST_CHILD_INDENT_AS_BLOCK_INDENT;
AbstractBlockWrapper current = this;
while (current != null && current.getStartOffset() == getStartOffset()) {
current.myFlags &= ~CAN_USE_FIRST_CHILD_INDENT_AS_BLOCK_INDENT;
current = current.myParent;
if (childStartsNewLine) {
if (child.getIndent().isAbsolute()) {
myFlags &= ~CAN_USE_FIRST_CHILD_INDENT_AS_BLOCK_INDENT;
AbstractBlockWrapper current = this;
while (current != null && current.getStartOffset() == getStartOffset()) {
current.myFlags &= ~CAN_USE_FIRST_CHILD_INDENT_AS_BLOCK_INDENT;
current = current.myParent;
}
return childIndent;
}
else if (options.USE_RELATIVE_INDENTS && child.getStartOffset() > getStartOffset()
&& (CONTINUATION_INDENT_TYPES.contains(childIndentType)))
{
return childIndent.add(getNumberOfSymbolsBeforeBlock());
}
return childIndent;
}
if (child.getStartOffset() == getStartOffset()) {
@@ -192,25 +207,25 @@ public abstract class AbstractBlockWrapper {
setCanUseFirstChildIndentAsBlockIndent(newValue);
}
if (getStartOffset() == tokenBlockStartOffset) {
if (getStartOffset() == targetBlockStartOffset) {
if (myParent == null) {
return childIndent;
}
else {
return childIndent.add(myParent.getChildOffset(this, options, tokenBlockStartOffset));
return childIndent.add(myParent.getChildOffset(this, options, targetBlockStartOffset));
}
} else if (!getWhiteSpace().containsLineFeeds()) {
if (isIndentAffectedAlignment(child)) {
return createAlignmentIndent(childIndent, child);
}
else {
return childIndent.add(myParent.getChildOffset(this, options, tokenBlockStartOffset));
return childIndent.add(myParent.getChildOffset(this, options, targetBlockStartOffset));
}
} else {
if (myParent == null) return childIndent.add(getWhiteSpace());
if (getIndent().isAbsolute()) {
if (myParent.myParent != null) {
return childIndent.add(myParent.myParent.getChildOffset(myParent, options, tokenBlockStartOffset));
return childIndent.add(myParent.myParent.getChildOffset(myParent, options, targetBlockStartOffset));
}
else {
return childIndent.add(getWhiteSpace());
@@ -225,7 +240,7 @@ public abstract class AbstractBlockWrapper {
}
}
else {
return childIndent.add(myParent.getChildOffset(this, options, tokenBlockStartOffset));
return childIndent.add(myParent.getChildOffset(this, options, targetBlockStartOffset));
}
}
}
@@ -252,7 +267,7 @@ public abstract class AbstractBlockWrapper {
* @return previous block for the current block if any; <code>null</code> otherwise
*/
@Nullable
protected abstract AbstractBlockWrapper getPreviousBlock();
protected abstract LeafBlockWrapper getPreviousBlock();
protected final void setCanUseFirstChildIndentAsBlockIndent(final boolean newValue) {
if (newValue) myFlags |= CAN_USE_FIRST_CHILD_INDENT_AS_BLOCK_INDENT;
@@ -287,10 +302,12 @@ public abstract class AbstractBlockWrapper {
}
/**
* Allows to answer if indent for the given child block should be calculated
* Allows to answer if indent for the given child block should be calculated taking into consideration alignment
* of the text at current block start.
*
* @param child
* @return
* @param child child block to check
* @return <code>true</code> if indent should be calculated taking into consideration alignment of the text at current
* block start; <code>false</code> otherwise
*/
private boolean isIndentAffectedAlignment(AbstractBlockWrapper child) {
if (!child.getWhiteSpace().containsLineFeeds()) {
@@ -75,7 +75,7 @@ public class CompositeBlockWrapper extends AbstractBlockWrapper{
}
@Override
protected AbstractBlockWrapper getPreviousBlock() {
protected LeafBlockWrapper getPreviousBlock() {
if (myChildren == null || myChildren.isEmpty()) {
return null;
}
@@ -151,8 +151,6 @@ class LeafBlockWrapper extends AbstractBlockWrapper {
return new IndentData(indentSpaces, spaces);
}
public void dispose() {
super.dispose();
myPreviousBlock = null;
@@ -230,9 +228,4 @@ class LeafBlockWrapper extends AbstractBlockWrapper {
public TextRange getTextRange() {
return new TextRange(myStart, myEnd);
}
private void calculateNumberOfSymbolsAtLastLine() {
}
}
@@ -340,6 +340,7 @@ editbox.indent.continuation.indent=Continuation indent
editbox.indent.label.indent=Label indent
checkbox.indent.absolute.label.indent=Absolute label indent
checkbox.do.not.indent.top.level.class.members=Do not indent top level class members
checkbox.use.relative.indents=Use indents relative to expression start
tooltip.indent.must.be.multiple.of.tab.size.for.smart.tabs.to.operate=Indent must be multiple of tab size for smart tabs to operate
combobox.crlf.system.dependent=System Dependent
combobox.crlf.unix=Unix \n
@@ -60,19 +60,20 @@ public class SMTestRunnerConnectionUtil {
* consistency of test events communication protocol and throw assertion errors. To enable debug mode
* please set system property idea.smrunner.debug=true
*
* @param processHandler Process handler
* @param consoleProperties Console properties for test console actions
* @param testFrameworkName Is used to store(project level) latest value of testTree/consoleTab splitter and other settings
* and also will be mentioned in debug diagnostics
* @param processHandler Process handler
* @param consoleProperties Console properties for test console actions
* @return Console view
* @throws ExecutionException If IDEA cannot execute process this Exception will
* be caught and shown in error message box
*/
public static BaseTestsOutputConsoleView attachRunner(@NotNull final ProcessHandler processHandler,
public static BaseTestsOutputConsoleView attachRunner(@NotNull final String testFrameworkName,
@NotNull final ProcessHandler processHandler,
@NotNull final TestConsoleProperties consoleProperties,
final RunnerSettings runnerSettings,
final ConfigurationPerRunnerSettings configurationSettings,
@NotNull final String testFrameworkName) throws ExecutionException {
final ConfigurationPerRunnerSettings configurationSettings
) throws ExecutionException {
// Console
final String splitterPropertyName = testFrameworkName + ".Splitter.Proportion";
@@ -126,24 +127,24 @@ public class SMTestRunnerConnectionUtil {
* consistency of test events communication protocol and throw assertion errors. To enable debug mode
* please set system property idea.smrunner.debug=true
*
* @param testFrameworkName Is used to store(project level) latest value of testTree/consoleTab splitter and other settings
* @param processHandler Process handler
* @param commandLineState Command line state
* @param config User run configuration settings
* @param testFrameworkName Is used to store(project level) latest value of testTree/consoleTab splitter and other settings
* @return Console view
* @throws ExecutionException If IDEA cannot execute process this Exception will
* be caught and shown in error message box
*/
public static ConsoleView attachRunner(@NotNull final ProcessHandler processHandler,
public static ConsoleView attachRunner(@NotNull final String testFrameworkName, @NotNull final ProcessHandler processHandler,
@NotNull final CommandLineState commandLineState,
@NotNull final RuntimeConfiguration config,
@NotNull final String testFrameworkName) throws ExecutionException {
@NotNull final RuntimeConfiguration config
) throws ExecutionException {
// final String testFrameworkName
final TestConsoleProperties consoleProperties = new SMTRunnerConsoleProperties(config, testFrameworkName);
return attachRunner(processHandler, consoleProperties,
return attachRunner(testFrameworkName, processHandler, consoleProperties,
commandLineState.getRunnerSettings(),
commandLineState.getConfigurationSettings(), testFrameworkName);
commandLineState.getConfigurationSettings());
}
/**
@@ -642,7 +642,7 @@ public class ContainerUtil {
return result;
}
public static <T, V> List<V> mapNotNull(T[] array, Function<T, V> mapping) {
public static <T, V> List<V> mapNotNull(@NotNull T[] array, Function<T, V> mapping) {
return mapNotNull(Arrays.asList(array), mapping);
}
@@ -98,6 +98,7 @@ public class GrDocCommentImpl extends LazyParseablePsiElement implements GroovyD
return list.toArray(new GrDocTag[list.size()]);
}
@NotNull
public PsiElement[] getDescriptionElements() {
ArrayList<PsiElement> array = new ArrayList<PsiElement>();
for (PsiElement child = getFirstChild(); child != null; child = child.getNextSibling()) {
@@ -46,6 +46,7 @@ class HgIncomingStatusUpdater implements HgUpdater {
public void run() {
new Task.Backgroundable(project, "Checking Incoming Changesets", true) {
public void run(@NotNull ProgressIndicator indicator) {
if (project.isDisposed()) return;
HgIncomingCommand command = new HgIncomingCommand(project);
VcsRoot[] roots = ProjectLevelVcsManager.getInstance(project).getAllVcsRoots();
List<HgFileRevision> changesets = new LinkedList<HgFileRevision>();
@@ -57,7 +58,7 @@ class HgIncomingStatusUpdater implements HgUpdater {
}
}.queue();
}
});
}, project.getDisposed());
}
private final class IncomingChangesetFormatter implements HgChangesetStatus.ChangesetWriter {
@@ -46,6 +46,7 @@ class HgOutgoingStatusUpdater implements HgUpdater {
public void run() {
new Task.Backgroundable(project, "Checking Outgoing Changesets", true) {
public void run(@NotNull ProgressIndicator indicator) {
if (project.isDisposed()) return;
HgOutgoingCommand command = new HgOutgoingCommand(project);
VcsRoot[] roots = ProjectLevelVcsManager.getInstance(project).getAllVcsRoots();
List<HgFileRevision> outgoing = new LinkedList<HgFileRevision>();
@@ -57,7 +58,7 @@ class HgOutgoingStatusUpdater implements HgUpdater {
}
}.queue();
}
});
}, project.getDisposed());
}
private final class OutgoingChangesetFormatter implements HgChangesetStatus.ChangesetWriter {
@@ -189,16 +189,21 @@ public class HgVcs extends AbstractVcs {
}
@Override
protected void start() throws VcsException {
protected void activate() {
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
HgExecutableValidator validator = new HgExecutableValidator(myProject);
started = validator.check(globalSettings);
if (ApplicationManager.getApplication().isUnitTestMode()) {
started = true;
}
else {
HgExecutableValidator validator = new HgExecutableValidator(myProject);
started = validator.check(globalSettings);
}
if (isStarted()) {
addListeners();
}
}
});
}, myProject.getDisposed());
}
@Override
@@ -29,6 +29,7 @@ import com.intellij.psi.xml.XmlTokenType;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.HashSet;
import com.intellij.util.containers.IntArrayList;
import com.intellij.xml.util.HtmlUtil;
import org.jetbrains.annotations.Nullable;
import java.util.*;
@@ -310,27 +311,38 @@ class XmlZenCodingInterpreter {
if (token instanceof XmlTemplateToken && token.getTemplate() != null) {
XmlTemplateToken xmlTemplateToken = (XmlTemplateToken)token;
List<Pair<String, String>> attr2value = new ArrayList<Pair<String, String>>(xmlTemplateToken.getAttribute2Value());
if (attr2value.size() > 0 || XmlZenCodingTemplate.isTrueXml(callback)) {
TemplateImpl modifiedTemplate = token.getTemplate().copy();
XmlTag tag = xmlTemplateToken.getTag();
if (tag != null) {
for (Iterator<Pair<String, String>> iterator = attr2value.iterator(); iterator.hasNext();) {
Pair<String, String> pair = iterator.next();
if (tag.getAttribute(pair.first) != null) {
tag.setAttribute(pair.first, ZenCodingUtil.getValue(pair, numberInIteration));
iterator.remove();
}
TemplateImpl modifiedTemplate = token.getTemplate().copy();
XmlTag tag = xmlTemplateToken.getTag();
if (tag != null) {
for (Iterator<Pair<String, String>> iterator = attr2value.iterator(); iterator.hasNext();) {
Pair<String, String> pair = iterator.next();
if (tag.getAttribute(pair.first) != null) {
tag.setAttribute(pair.first, ZenCodingUtil.getValue(pair, numberInIteration));
iterator.remove();
}
String s = filterXml(tag, callback, filter);
assert s != null;
modifiedTemplate.setString(s);
removeVariablesWhichHasNoSegment(modifiedTemplate);
Map<String, String> predefinedValues = buildPredefinedValues(attr2value, numberInIteration, callback);
callback.expandTemplate(modifiedTemplate, predefinedValues);
return;
}
String s = filterXml(tag, callback, filter);
assert s != null;
if (HtmlUtil.isHtmlBlockTagL(tag.getName())) {
boolean newLineBefore = callback.newLineBefore();
boolean newLineAfter = callback.newLineAfter();
if (!newLineBefore || !newLineAfter) {
StringBuilder builder = new StringBuilder();
if (!newLineBefore) {
builder.append('\n');
}
builder.append(s);
if (!newLineAfter) {
builder.append('\n');
}
s = builder.toString();
}
}
modifiedTemplate.setString(s);
removeVariablesWhichHasNoSegment(modifiedTemplate);
Map<String, String> predefinedValues = buildPredefinedValues(attr2value, numberInIteration, callback);
callback.expandTemplate(modifiedTemplate, predefinedValues);
}
callback.expandTemplate(token.getTemplate(), null);
}
else {
// for CSS