Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ilya.Kazakevich
2015-02-10 01:09:05 +03:00
458 changed files with 5123 additions and 3185 deletions
@@ -189,8 +189,8 @@ public class StudyEditInputAction extends DumbAwareAction {
@Override
public void update(final AnActionEvent e) {
e.getPresentation().setIcon(tabbedPane.isEditorTabs() ? AllIcons.Actions.CloseNew : AllIcons.Actions.Close);
e.getPresentation().setHoveredIcon(tabbedPane.isEditorTabs() ? AllIcons.Actions.CloseNewHovered : AllIcons.Actions.CloseHovered);
e.getPresentation().setIcon(AllIcons.Actions.Close);
e.getPresentation().setHoveredIcon(AllIcons.Actions.CloseHovered);
e.getPresentation().setVisible(UISettings.getInstance().SHOW_CLOSE_BUTTON);
e.getPresentation().setText("Delete test");
}
@@ -16,12 +16,12 @@
package com.jetbrains.python.formatter;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.impl.source.codeStyle.PreFormatProcessor;
@@ -31,6 +31,9 @@ import com.jetbrains.python.psi.PyElementGenerator;
import com.jetbrains.python.psi.PyRecursiveElementVisitor;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* @author traff
*/
@@ -58,6 +61,7 @@ public class PyPreFormatProcessor implements PreFormatProcessor {
private final Project myProject;
private final CodeStyleSettings mySettings;
private final PyCodeStyleSettings myPyCodeStyleSettings;
private final List<Couple<PsiComment>> myCommentReplacements = new ArrayList<Couple<PsiComment>>();
private TextRange myRange;
private int myDelta = 0;
@@ -72,34 +76,62 @@ public class PyPreFormatProcessor implements PreFormatProcessor {
return range;
}
myRange = range;
element.accept(this);
final PsiDocumentManager manager = PsiDocumentManager.getInstance(myProject);
final Document document = manager.getDocument(element.getContainingFile());
if (document != null) {
manager.doPostponedOperationsAndUnblockDocument(document);
try {
// collect all comments
element.accept(this);
for (Couple<PsiComment> pair : myCommentReplacements) {
pair.getFirst().replace(pair.getSecond());
}
}
finally {
manager.commitDocument(document);
}
}
return TextRange.create(range.getStartOffset(), range.getEndOffset() + myDelta);
}
@Override
public void visitComment(PsiComment element) {
if (!myRange.contains(element.getTextRange())) {
public void visitComment(PsiComment comment) {
if (!myRange.contains(comment.getTextRange())) {
return;
}
String text = element.getText();
int commentStart = text.indexOf('#');
if (commentStart != -1 && (commentStart + 1) < text.length()) {
char charAfterDash = text.charAt(commentStart + 1);
if (charAfterDash == '!' && element.getTextRange().getStartOffset() == 0) {
return; //shebang
final String origText = comment.getText();
final int commentStart = origText.indexOf('#');
if (commentStart != -1 && (commentStart + 1) < origText.length()) {
final char charAfterDash = origText.charAt(commentStart + 1);
if (charAfterDash == '!' && comment.getTextRange().getStartOffset() == 0) {
return; // shebang
}
if (charAfterDash == '#' || charAfterDash == ':') {
return; // doc comment
}
final String commentTextWithoutDash = origText.substring(commentStart + 1);
final String newText;
if (isTrailingComment(comment)) {
newText = "# " + StringUtil.trimLeading(commentTextWithoutDash);
}
else if (!StringUtil.isWhiteSpace(charAfterDash)) {
newText = "# " + commentTextWithoutDash;
}
else {
return;
}
String commentText = StringUtil.trimLeading(text.substring(commentStart + 1));
String newText = "# " + commentText;
if (!newText.equals(text)) {
myDelta += newText.length() - text.length();
element.replace(
PyElementGenerator.getInstance(myProject).createFromText(LanguageLevel.getDefault(), PsiComment.class, newText));
if (!newText.equals(origText)) {
myDelta += newText.length() - origText.length();
final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(myProject);
final PsiComment newComment = elementGenerator.createFromText(LanguageLevel.forElement(comment), PsiComment.class, newText);
myCommentReplacements.add(Couple.of(comment, newComment));
}
}
}
}
private static boolean isTrailingComment(@NotNull PsiComment comment) {
final PsiElement prevElement = comment.getPrevSibling();
return prevElement != null && (!(prevElement instanceof PsiWhiteSpace) || !prevElement.textContains('\n'));
}
}
@@ -23,7 +23,7 @@ import com.jetbrains.python.psi.PyClass;
* @author yole
*/
public class PyClassInheritorsSearch extends ExtensibleQueryFactory<PyClass, PyClassInheritorsSearch.SearchParameters> {
public static PyClassInheritorsSearch INSTANCE = new PyClassInheritorsSearch();
public static final PyClassInheritorsSearch INSTANCE = new PyClassInheritorsSearch();
public static class SearchParameters {
private final PyClass mySuperClass;
@@ -28,7 +28,7 @@ import java.util.List;
* @author yole
*/
public class PySuperMethodsSearch extends ExtensibleQueryFactory<PsiElement, PySuperMethodsSearch.SearchParameters> {
public static PySuperMethodsSearch INSTANCE = new PySuperMethodsSearch();
public static final PySuperMethodsSearch INSTANCE = new PySuperMethodsSearch();
private static PyFunction getBaseMethod(List<PsiElement> superMethods,
PyClass containingClass) {
@@ -0,0 +1,6 @@
# This normal comment won't be touched as well
# for a in [1, 2, 3]:
# if a == 1:
# print 'x'
# elif a == 2:
# print 'y'
@@ -0,0 +1,6 @@
# This normal comment won't be touched as well
# for a in [1, 2, 3]:
# if a == 1:
# print 'x'
# elif a == 2:
# print 'y'
@@ -0,0 +1,4 @@
#: :type: dict of (str, C)
d = {'foo': C()}
#: :type: list of str
xs = ['bar']
@@ -0,0 +1,4 @@
#: :type: dict of (str, C)
d = {'foo': C()}
#: :type: list of str
xs = ['bar']
@@ -0,0 +1,6 @@
###########
##
## MANUAL
##
print('Spam')
@@ -0,0 +1,6 @@
###########
##
## MANUAL
##
print('Spam')
@@ -0,0 +1,3 @@
# Whole-line commend that starts with whitespace.
if True: #Trailing comment with no whitespace
print 'Spam' # Trailing comment with excess whitespace
@@ -0,0 +1,3 @@
# Whole-line commend that starts with whitespace.
if True: # Trailing comment with no whitespace
print 'Spam' # Trailing comment with excess whitespace
@@ -0,0 +1,4 @@
#some
#invalid
#pep-8
#comment
@@ -0,0 +1,4 @@
# some
# invalid
# pep-8
# comment
@@ -401,10 +401,6 @@ public class PyFormatterTest extends PyTestCase {
doTest();
}
public void testShebang() { //PY-12775
doTest();
}
public void testParenthesisAroundGeneratorExpression() {
doTest();
}
@@ -483,13 +479,43 @@ public class PyFormatterTest extends PyTestCase {
// PY-12748
public void testIndentCommentariesInsideFromImportStatement() {
doTest();
doTest();
}
public void testClosingParenthesisInFromImportStatementWithNoHangingIndent() {
doTest();
}
// PY-12932
public void testCommentedCodeFragmentIgnored() {
doTest();
}
// PY-12932
public void testTrailingComment() {
doTest();
}
// PY-12938
public void testDoubleHashCommentIgnored() {
doTest();
}
// PY-12938
public void testDocCommentIgnored() {
doTest();
}
// PY-12775
public void testShebangCommentIgnored() {
doTest();
}
// PY-13232
public void testWhitespaceInsertedAfterHashSignInMultilineComment() {
doTest();
}
/**
* This test merely checks that call to {@link com.intellij.psi.codeStyle.CodeStyleManager#reformat(com.intellij.psi.PsiElement)}
* is possible for Python sources.