Merge branch 'master' into upsource-master

This commit is contained in:
Evgeny Pasynkov
2012-07-16 11:53:16 +02:00
160 changed files with 6194 additions and 5503 deletions
@@ -28,7 +28,7 @@ import com.intellij.ide.DataManager;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.command.undo.UndoUtil;
import com.intellij.openapi.command.undo.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
@@ -358,6 +358,18 @@ public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
}
}
}.execute();
UndoManager.getInstance(project).undoableActionPerformed(new BasicUndoableAction() {
@Override
public void undo() throws UnexpectedUndoException {
dropCache();
}
@Override
public void redo() throws UnexpectedUndoException {
dropCache();
}
});
}
@Override
@@ -105,12 +105,43 @@ class StatementMover extends LineMover {
return true;
}
private boolean calcInsertOffset(PsiFile file, final Editor editor, LineRange range, @NotNull final MoveInfo info, final boolean down) {
int line = down ? range.endLine+1 : range.startLine - 1;
private int getDestLineForAnon(PsiFile file, Editor editor, LineRange range, MoveInfo info, boolean down) {
int destLine = down ? range.endLine+1 : range.startLine - 1;
if (!(range.firstElement instanceof PsiStatement)) {
return destLine;
}
PsiElement sibling =
StatementUpDownMover.firstNonWhiteElement(down ? range.firstElement.getNextSibling() : range.firstElement.getPrevSibling(), down);
PsiElement toMove = sibling;
if (!(sibling instanceof PsiStatement)) {
return destLine;
}
if (sibling instanceof PsiDeclarationStatement) {
PsiElement[] elements = ((PsiDeclarationStatement)sibling).getDeclaredElements();
if (elements.length == 0) return destLine;
sibling = down ? elements[elements.length - 1] : elements[0];
}
if (sibling instanceof PsiVariable) {
sibling = ((PsiVariable)sibling).getInitializer();
}
if (sibling instanceof PsiExpressionStatement) {
sibling = ((PsiExpressionStatement)sibling).getExpression();
}
if (sibling instanceof PsiNewExpression) {
sibling = ((PsiNewExpression)sibling).getAnonymousClass();
}
if (!(sibling instanceof PsiClass)) return destLine;
destLine = editor.getDocument().getLineNumber(down ? toMove.getTextRange().getEndOffset() : toMove.getTextRange().getStartOffset());
return destLine;
}
private boolean calcInsertOffset(@NotNull PsiFile file, @NotNull Editor editor, @NotNull LineRange range, @NotNull final MoveInfo info, final boolean down) {
int destLine = getDestLineForAnon(file, editor, range, info, down);
int startLine = down ? range.endLine : range.startLine - 1;
if (line < 0 || startLine < 0) return false;
if (destLine < 0 || startLine < 0) return false;
while (true) {
final int offset = editor.logicalPositionToOffset(new LogicalPosition(line, 0));
final int offset = editor.logicalPositionToOffset(new LogicalPosition(destLine, 0));
PsiElement element = firstNonWhiteElement(offset, file, true);
while (element != null && !(element instanceof PsiFile)) {
@@ -133,7 +164,7 @@ class StatementMover extends LineMover {
if (found) {
statementToSurroundWithCodeBlock = elementToSurround;
info.toMove = range;
int endLine = line;
int endLine = destLine;
if (startLine > endLine) {
int tmp = endLine;
endLine = startLine;
@@ -146,8 +177,8 @@ class StatementMover extends LineMover {
}
element = element.getParent();
}
line += down ? 1 : -1;
if (line == 0 || line >= editor.getDocument().getLineCount()) {
destLine += down ? 1 : -1;
if (destLine == 0 || destLine >= editor.getDocument().getLineCount()) {
return false;
}
}
@@ -125,20 +125,18 @@ public class DeannotateIntentionAction implements IntentionAction {
@Override
public void invoke(@NotNull final Project project, Editor editor, final PsiFile file) throws IncorrectOperationException {
final PsiModifierListOwner listOwner = getContainer(editor, file);
LOG.assertTrue(listOwner != null);
final ExternalAnnotationsManager annotationsManager = ExternalAnnotationsManager.getInstance(project);
final PsiAnnotation[] externalAnnotations = annotationsManager.findExternalAnnotations(listOwner);
LOG.assertTrue(externalAnnotations != null && externalAnnotations.length > 0);
if (externalAnnotations.length == 1) {
deannotate(externalAnnotations[0], project, file, annotationsManager, listOwner);
return;
}
JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep<PsiAnnotation>(CodeInsightBundle.message("deannotate.intention.chooser.title"), externalAnnotations) {
@Override
public PopupStep onChosen(final PsiAnnotation selectedValue, final boolean finalChoice) {
new WriteCommandAction(project){
@Override
protected void run(final Result result) throws Throwable {
final VirtualFile virtualFile = file.getVirtualFile();
if (annotationsManager.deannotate(listOwner, selectedValue.getQualifiedName()) && virtualFile != null && virtualFile.isInLocalFileSystem()) {
UndoUtil.markPsiFileForUndo(file);
}
}
}.execute();
deannotate(selectedValue, project, file, annotationsManager, listOwner);
return PopupStep.FINAL_CHOICE;
}
@@ -152,6 +150,24 @@ public class DeannotateIntentionAction implements IntentionAction {
}).showInBestPositionFor(editor);
}
private void deannotate(final PsiAnnotation annotation,
final Project project,
final PsiFile file,
final ExternalAnnotationsManager annotationsManager,
final PsiModifierListOwner listOwner) {
new WriteCommandAction(project, getText()) {
@Override
protected void run(final Result result) throws Throwable {
final VirtualFile virtualFile = file.getVirtualFile();
String qualifiedName = annotation.getQualifiedName();
LOG.assertTrue(qualifiedName != null);
if (annotationsManager.deannotate(listOwner, qualifiedName) && virtualFile != null && virtualFile.isInLocalFileSystem()) {
UndoUtil.markPsiFileForUndo(file);
}
}
}.execute();
}
@Override
public boolean startInWriteAction() {
return false;
@@ -49,6 +49,8 @@ import com.intellij.psi.impl.source.jsp.jspJava.JspCodeBlock;
import com.intellij.psi.impl.source.jsp.jspJava.JspHolderMethod;
import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy;
import com.intellij.psi.impl.source.tree.java.ReplaceExpressionUtil;
import com.intellij.psi.scope.processor.VariablesProcessor;
import com.intellij.psi.scope.util.PsiScopesUtil;
import com.intellij.psi.util.PsiExpressionTrimRenderer;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
@@ -522,21 +524,9 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, file)) return false;
PsiElement containerParent = tempContainer;
PsiElement lastScope = tempContainer;
while (true) {
if (containerParent instanceof PsiFile) break;
if (containerParent instanceof PsiMethod) break;
containerParent = containerParent.getParent();
if (containerParent instanceof PsiCodeBlock) {
lastScope = containerParent;
}
}
final ExpressionOccurrenceManager occurenceManager = new ExpressionOccurrenceManager(expr, lastScope,
NotInSuperCallOccurrenceFilter.INSTANCE);
final PsiExpression[] occurrences = occurenceManager.getOccurrences();
final PsiElement anchorStatementIfAll = occurenceManager.getAnchorStatementForAll();
final ExpressionOccurrenceManager occurrenceManager = createOccurrenceManager(expr, tempContainer);
final PsiExpression[] occurrences = occurrenceManager.getOccurrences();
final PsiElement anchorStatementIfAll = occurrenceManager.getAnchorStatementForAll();
final LinkedHashMap<OccurrencesChooser.ReplaceChoice, List<PsiExpression>> occurrencesMap = ContainerUtil.newLinkedHashMap();
@@ -550,8 +540,8 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
supportProvider.isInplaceIntroduceAvailable(expr, nameSuggestionContext) &&
!ApplicationManager.getApplication().isUnitTestMode() &&
!isInJspHolderMethod(expr);
final boolean inFinalContext = occurenceManager.isInFinalContext();
final InputValidator validator = new InputValidator(this, project, anchorStatementIfAll, anchorStatement, occurenceManager);
final boolean inFinalContext = occurrenceManager.isInFinalContext();
final InputValidator validator = new InputValidator(this, project, anchorStatementIfAll, anchorStatement, occurrenceManager);
final TypeSelectorManagerImpl typeSelectorManager = new TypeSelectorManagerImpl(project, originalType, expr, occurrences);
final boolean[] wasSucceed = new boolean[]{true};
final Pass<OccurrencesChooser.ReplaceChoice> callback = new Pass<OccurrencesChooser.ReplaceChoice>() {
@@ -613,6 +603,35 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
return wasSucceed[0];
}
private static ExpressionOccurrenceManager createOccurrenceManager(PsiExpression expr, PsiElement tempContainer) {
boolean skipForStatement = true;
final PsiForStatement forStatement = PsiTreeUtil.getParentOfType(expr, PsiForStatement.class);
if (forStatement != null) {
final VariablesProcessor variablesProcessor = new VariablesProcessor(false) {
@Override
protected boolean check(PsiVariable var, ResolveState state) {
return PsiTreeUtil.isAncestor(forStatement.getInitialization(), var, true);
}
};
PsiScopesUtil.treeWalkUp(variablesProcessor, expr, null);
skipForStatement = variablesProcessor.size() == 0;
}
PsiElement containerParent = tempContainer;
PsiElement lastScope = tempContainer;
while (true) {
if (containerParent instanceof PsiFile) break;
if (containerParent instanceof PsiMethod) break;
if (!skipForStatement && containerParent instanceof PsiForStatement) break;
containerParent = containerParent.getParent();
if (containerParent instanceof PsiCodeBlock) {
lastScope = containerParent;
}
}
return new ExpressionOccurrenceManager(expr, lastScope, NotInSuperCallOccurrenceFilter.INSTANCE);
}
private static boolean isInJspHolderMethod(PsiExpression expr) {
final PsiElement parent1 = expr.getParent();
if (parent1 == null) {