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

This commit is contained in:
Kirill Kalishev
2011-05-20 16:26:39 +04:00
9 changed files with 209 additions and 78 deletions
@@ -48,6 +48,9 @@ public abstract class GenericsInspectionToolBase extends BaseLocalInspectionTool
if (initializer != null) {
return getDescriptions(initializer, manager, isOnTheFly);
}
if (field instanceof PsiEnumConstant) {
return getDescriptions(field, manager, isOnTheFly);
}
return null;
}
@@ -1127,17 +1127,41 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
if (parent == null || parent.getElementType() != JavaElementType.METHOD_CALL_EXPRESSION) {
return false;
}
if (node.getElementType() != JavaElementType.NEW_EXPRESSION) {
return false;
}
ASTNode lastChild = node.getLastChildNode();
if (lastChild == null || lastChild.getElementType() != JavaElementType.ANONYMOUS_CLASS) {
if (!isAnonymousClass(node)) {
return false;
}
// Enforce indent only if anonymous class instance expression doesn't start new line.
// Enforce indent only if anonymous class instance expression doesn't start new line and have anonymous class expression sibling.
ASTNode prev = node.getTreePrev();
return prev == null || prev.getElementType() != TokenType.WHITE_SPACE || !StringUtil.containsLineBreak(prev.getChars());
if (prev == null || (StringUtil.containsLineBreak(prev.getChars()) && prev.getElementType() != TokenType.WHITE_SPACE)) {
return false;
}
final PsiElement psi = myNode.getPsi();
if (!(psi instanceof PsiExpressionList)) {
return false;
}
PsiExpressionList expressionList = (PsiExpressionList)psi;
for (PsiExpression expression : expressionList.getExpressions()) {
final ASTNode argumentNode = expression.getNode();
if (argumentNode == node) {
continue;
}
if (isAnonymousClass(argumentNode)) {
return true;
}
}
return false;
}
private static boolean isAnonymousClass(@Nullable ASTNode node) {
if (node == null || node.getElementType() != JavaElementType.NEW_EXPRESSION) {
return false;
}
ASTNode lastChild = node.getLastChildNode();
return lastChild != null && lastChild.getElementType() == JavaElementType.ANONYMOUS_CLASS;
}
@Nullable
@@ -422,6 +422,18 @@ public class JavaFormatterIndentationTest extends AbstractJavaFormatterTest {
");"
);
doMethodTest(
"foo(new Runnable() {\n" +
"@Override\n" +
"public void run() {\n" +
"}" +
"}, 1, 2);",
"foo(new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" }\n" +
"}, 1, 2);"
);
}
public void testPackagePrivateAnnotation() {
@@ -25,10 +25,7 @@ import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
/**
* @author max
@@ -42,7 +39,11 @@ public class RedundantCastUtil {
@NotNull
public static List<PsiTypeCastExpression> getRedundantCastsInside(PsiElement where) {
MyCollectingVisitor visitor = new MyCollectingVisitor();
where.acceptChildren(visitor);
if (where instanceof PsiEnumConstant) {
where.accept(visitor);
} else {
where.acceptChildren(visitor);
}
return new ArrayList<PsiTypeCastExpression>(visitor.myFoundCasts);
}
@@ -247,11 +248,17 @@ public class RedundantCastUtil {
super.visitNewExpression(expression);
}
@Override
public void visitEnumConstant(PsiEnumConstant enumConstant) {
processCall(enumConstant);
super.visitEnumConstant(enumConstant);
}
@Override public void visitReferenceExpression(PsiReferenceExpression expression) {
//expression.acceptChildren(this);
}
private void processCall(PsiCallExpression expression){
private void processCall(PsiCall expression){
PsiExpressionList argumentList = expression.getArgumentList();
if (argumentList == null) return;
PsiExpression[] args = argumentList.getExpressions();
@@ -268,7 +275,7 @@ public class RedundantCastUtil {
//do not mark cast to resolve ambiguity for calling varargs method with inexact argument
continue;
}
PsiCallExpression newCall = (PsiCallExpression) expression.copy();
PsiCall newCall = (PsiCall) expression.copy();
final PsiExpressionList argList = newCall.getArgumentList();
LOG.assertTrue(argList != null);
PsiExpression[] newArgs = argList.getExpressions();
@@ -276,10 +283,22 @@ public class RedundantCastUtil {
PsiExpression castOperand = castExpression.getOperand();
if (castOperand == null) return;
castExpression.replace(castOperand);
final JavaResolveResult newResult = newCall.resolveMethodGenerics();
if (oldMethod.equals(newResult.getElement()) && newResult.isValidResult() &&
Comparing.equal(newCall.getType(), expression.getType())) {
addToResults(cast);
if (newCall instanceof PsiEnumConstant) {
// do this manually, because PsiEnumConstantImpl.resolveMethodGenerics() will assert (no containing class for the copy)
final PsiEnumConstant enumConstant = (PsiEnumConstant)expression;
PsiClass containingClass = enumConstant.getContainingClass();
final JavaPsiFacade facade = JavaPsiFacade.getInstance(enumConstant.getProject());
final PsiClassType type = facade.getElementFactory().createType(containingClass);
final JavaResolveResult newResult = facade.getResolveHelper().resolveConstructor(type, newCall.getArgumentList(), enumConstant);
if (oldMethod.equals(newResult.getElement()) && newResult.isValidResult()) {
addToResults(cast);
}
} else {
final JavaResolveResult newResult = newCall.resolveMethodGenerics();
if (oldMethod.equals(newResult.getElement()) && newResult.isValidResult() &&
Comparing.equal(((PsiCallExpression)newCall).getType(), ((PsiCallExpression)expression).getType())) {
addToResults(cast);
}
}
}
}
@@ -36,6 +36,7 @@ import com.intellij.openapi.editor.event.SelectionListener;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.ui.LightColors;
@@ -93,6 +94,8 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
private MyLivePreviewController myLivePreviewController;
private LivePreview myLivePreview;
private boolean mySupressUpdate = false;
private boolean myListeningSelection = false;
private SearchResults mySearchResults;
@@ -110,16 +113,6 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
@Override
public void replaceAllPerformed(Editor e) { }
@Override
public void replaceDenied() {
updateReplaceButton();
}
@Override
public void replaceAllowed() {
updateReplaceButton();
}
private void updateReplaceButton() {
if (myReplaceButton != null) {
myReplaceButton.setEnabled(mySearchResults != null && mySearchResults.getCursor() != null &&
@@ -650,7 +643,12 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
private void initLivePreview() {
myDocumentListener = new DocumentAdapter() {
public void documentChanged(final DocumentEvent e) {
updateResults(false);
if (!mySupressUpdate) {
myLivePreview.inSmartUpdate();
updateResults(false);
} else {
mySupressUpdate = false;
}
}
};
@@ -787,8 +785,12 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec
}
public void performReplace() {
mySupressUpdate = true;
String replacement = getStringToReplace(myEditor, mySearchResults.getCursor());
performReplace(mySearchResults.getCursor(), replacement, myEditor);
final TextRange textRange = performReplace(mySearchResults.getCursor(), replacement, myEditor);
if (textRange == null) {
mySupressUpdate = false;
}
//getFocusBack();
addTextToRecents(myReplaceField) ;
}
@@ -50,13 +50,27 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele
private static final Key<Object> IN_SELECTION_KEY = Key.create("LivePreview.IN_SELECTION_KEY");
private static final Object IN_SELECTION1 = new Object();
private static final Object IN_SELECTION2 = new Object();
private boolean myListeningSelection = false;
private boolean mySuppressedUpdate = false;
private boolean myInSmartUpdate = false;
private static final Key<Object> MARKER_USED = Key.create("LivePreview.MARKER_USED");
private static final Object YES = new Object();
@Override
public void selectionChanged(SelectionEvent e) {
updateInSelectionHighlighters();
}
public void supressUpdate() {
mySuppressedUpdate = true;
}
public void inSmartUpdate() {
myInSmartUpdate = true;
}
public interface Delegate {
@Nullable
@@ -120,10 +134,38 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele
@Override
public void searchResultsUpdated(SearchResults sr) {
if (mySearchResults.getProject().isDisposed()) return;
removeFromEditor(mySearchResults.getEditor());
if (mySuppressedUpdate) {
mySuppressedUpdate = false;
return;
}
if (!myInSmartUpdate) {
removeFromEditor();
}
highlightUsages();
updateCursorHighlighting(false);
if (myInSmartUpdate) {
clearUnusedHightlighters();
myInSmartUpdate = false;
}
}
private void clearUnusedHightlighters() {
Set<RangeHighlighter> unused = new com.intellij.util.containers.HashSet<RangeHighlighter>();
for (RangeHighlighter highlighter : myHighlighters) {
if (highlighter.getUserData(MARKER_USED) == null) {
unused.add(highlighter);
} else {
highlighter.putUserData(MARKER_USED, null);
}
}
myHighlighters.removeAll(unused);
Project project = mySearchResults.getProject();
if (!project.isDisposed()) {
for (RangeHighlighter highlighter : unused) {
HighlightManager.getInstance(project).removeSegmentHighlighter(mySearchResults.getEditor(), highlighter);
}
}
}
@Override
@@ -133,7 +175,7 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele
}
public void editorChanged(SearchResults sr, Editor oldEditor) {
removeFromEditor(mySearchResults.getEditor());
removeFromEditor();
oldEditor.getDocument().removeDocumentListener(this);
mySearchResults.getEditor().getDocument().addDocumentListener(this);
}
@@ -187,14 +229,15 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele
public void cleanUp() {
removeFromEditor(mySearchResults.getEditor());
removeFromEditor();
}
public void dispose() {
mySearchResults.removeListener(this);
}
private void removeFromEditor(Editor editor) {
private void removeFromEditor() {
Editor editor = mySearchResults.getEditor();
if (myReplacementBalloon != null) {
myReplacementBalloon.hide();
}
@@ -244,7 +287,7 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele
mySearchResults.getEditor().getSelectionModel().addSelectionListener(this);
myListeningSelection = true;
}
}
private void updateInSelectionHighlighters() {
@@ -319,13 +362,42 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele
@NotNull
private RangeHighlighter highlightRange(TextRange textRange, TextAttributes attributes, Collection<RangeHighlighter> highlighters) {
if (myInSmartUpdate) {
for (RangeHighlighter highlighter : myHighlighters) {
if (highlighter.isValid() && highlighter.getStartOffset() == textRange.getStartOffset() && highlighter.getEndOffset() == textRange.getEndOffset()) {
if (attributes.equals(highlighter.getTextAttributes())) {
highlighter.putUserData(MARKER_USED, YES);
if (highlighters != myHighlighters) {
highlighters.add(highlighter);
}
return highlighter;
}
}
}
}
final RangeHighlighter highlighter = doHightlightRange(textRange, attributes, highlighters);
if (myInSmartUpdate) {
highlighter.putUserData(MARKER_USED, YES);
}
return highlighter;
}
private RangeHighlighter doHightlightRange(TextRange textRange, TextAttributes attributes, Collection<RangeHighlighter> highlighters) {
HighlightManager highlightManager = HighlightManager.getInstance(mySearchResults.getProject());
final ArrayList<RangeHighlighter> dummy = new ArrayList<RangeHighlighter>();
highlightManager.addRangeHighlight(mySearchResults.getEditor(),
textRange.getStartOffset(), textRange.getEndOffset(),
attributes, false, dummy);
highlighters.addAll(dummy);
return dummy.get(0);
final RangeHighlighter h = dummy.get(0);
for (RangeHighlighter highlighter : highlighters) {
if (h.getStartOffset() == highlighter.getStartOffset() && h.getEndOffset() == highlighter.getEndOffset() &&
h.getTextAttributes().equals(highlighter.getTextAttributes())) {
return h;
}
}
highlighters.add(h);
return h;
}
@@ -64,7 +64,6 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil
@Override
public void searchResultsUpdated(SearchResults sr) {
setReplaceDenied(false);
}
@Override
@@ -89,24 +88,9 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil
return myReplaceDenied;
}
public void setReplaceDenied(final boolean replaceDenied) {
boolean changed = replaceDenied != myReplaceDenied;
myReplaceDenied = replaceDenied;
if (changed && myReplaceListener != null) {
if (replaceDenied) {
myReplaceListener.replaceDenied();
}
else {
myReplaceListener.replaceAllowed();
}
}
}
public interface ReplaceListener {
void replacePerformed(LiveOccurrence occurrence, final String replacement, final Editor editor);
void replaceAllPerformed(Editor e);
void replaceDenied();
void replaceAllowed();
}
private ReplaceListener myReplaceListener;
@@ -146,17 +130,6 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil
Runnable request = new Runnable() {
@Override
public void run() {
Runnable denyReplace = new Runnable() {
@Override
public void run() {
setReplaceDenied(true);
}
};
if (unitTestMode) {
denyReplace.run();
} else {
ApplicationManager.getApplication().invokeAndWait(denyReplace, modalityState);
}
mySearchResults.updateThreadSafe(copy, allowedToChangedEditorSelection, null, stamp);
}
};
@@ -213,7 +186,7 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil
if (myReplaceListener != null) {
myReplaceListener.replacePerformed(occurrence, replacement, editor);
}
setReplaceDenied(true);
myLivePreview.inSmartUpdate();
mySearchResults.updateThreadSafe(findModel, true, result, mySearchResults.getStamp());
return result;
}
@@ -249,9 +222,8 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil
@Override
public boolean shouldReplace(TextRange range, String replace) {
for (LiveOccurrence o : mySearchResults.getExcluded()) {
TextRange primaryRange = o.getPrimaryRange();
if (primaryRange.equals(range)) {
for (RangeMarker r : mySearchResults.getExcluded()) {
if (r.getStartOffset() == range.getStartOffset() && r.getEndOffset() == range.getEndOffset()) {
return false;
}
}
@@ -7,10 +7,12 @@ import com.intellij.find.FindResult;
import com.intellij.find.FindUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
@@ -34,7 +36,7 @@ public class SearchResults {
private List<LiveOccurrence> myOccurrences = new ArrayList<LiveOccurrence>();
private Set<LiveOccurrence> myExcluded = new HashSet<LiveOccurrence>();
private Set<RangeMarker> myExcluded = new HashSet<RangeMarker>();
private Editor myEditor;
private FindModel myFindModel;
@@ -72,19 +74,32 @@ public class SearchResults {
}
public boolean isExcluded(LiveOccurrence occurrence) {
return myExcluded.contains(occurrence);
for (RangeMarker rangeMarker : myExcluded) {
if (rangeMarker.getStartOffset() == occurrence.getPrimaryRange().getStartOffset() && rangeMarker.getEndOffset() == occurrence.getPrimaryRange().getEndOffset()) {
return true;
}
}
return false;
}
public void exclude(LiveOccurrence occurrence) {
if (myExcluded.contains(occurrence)) {
myExcluded.remove(occurrence);
} else {
myExcluded.add(occurrence);
boolean include = false;
final TextRange r = occurrence.getPrimaryRange();
for (RangeMarker rangeMarker : myExcluded) {
if (rangeMarker.getStartOffset() == r.getStartOffset() && rangeMarker.getEndOffset() == r.getEndOffset()) {
myExcluded.remove(rangeMarker);
rangeMarker.dispose();
include = true;
break;
}
}
if (!include) {
myExcluded.add(myEditor.getDocument().createRangeMarker(r.getStartOffset(), r.getEndOffset(), true));
}
notifyChanged();
}
public Set<LiveOccurrence> getExcluded() {
public Set<RangeMarker> getExcluded() {
return myExcluded;
}
@@ -230,6 +245,7 @@ public class SearchResults {
myFindModel = findModel;
updateCursor(oldCursorRange, next);
updateExcluded();
myActualFound = size;
notifyChanged();
if (oldCursorRange == null || myCursor == null || !myCursor.getPrimaryRange().equals(oldCursorRange)) {
@@ -238,6 +254,17 @@ public class SearchResults {
}
}
private void updateExcluded() {
Set<RangeMarker> invalid = new HashSet<RangeMarker>();
for (RangeMarker marker : myExcluded) {
if (!marker.isValid()) {
invalid.add(marker);
marker.dispose();
}
}
myExcluded.removeAll(invalid);
}
private void updateCursor(@Nullable TextRange oldCursorRange, @Nullable TextRange next) {
boolean justReplaced = next != null;
if (justReplaced || !tryToRepairOldCursor(oldCursorRange)) {
@@ -32,11 +32,11 @@ public class ServiceManager {
private ServiceManager() {
}
public static <T> T getService(Class<T> serviceClass) {
public static <T> T getService(@NotNull Class<T> serviceClass) {
return (T)ApplicationManager.getApplication().getPicoContainer().getComponentInstance(serviceClass.getName());
}
public static <T> T getService(Project project, Class<T> serviceClass) {
public static <T> T getService(@NotNull Project project, @NotNull Class<T> serviceClass) {
return (T)project.getPicoContainer().getComponentInstance(serviceClass.getName());
}
@@ -47,7 +47,7 @@ public class ServiceManager {
* @param <T> Service class type.
* @return Key instance.
*/
public static <T> NotNullLazyKey<T, Project> createLazyKey(final Class<T> serviceClass) {
public static <T> NotNullLazyKey<T, Project> createLazyKey(@NotNull final Class<T> serviceClass) {
return NotNullLazyKey.create("Service: " + serviceClass.getName(), new NotNullFunction<Project, T>() {
@NotNull
public T fun(Project project) {