IDEA-80414 Java: selecting completion result fires WrongOffset assertion

This commit is contained in:
peter
2012-02-01 20:56:01 +01:00
parent 9fd14da9af
commit 8e6bd961e6
5 changed files with 34 additions and 42 deletions
@@ -78,12 +78,12 @@ class ConstructorInsertHandler implements InsertHandler<LookupElementDecorator<L
PostprocessReformattingAspect.getInstance(context.getProject()).doPostponedFormatting(context.getFile().getViewProvider());
}
insertParentheses(context, delegate, psiClass, !inAnonymous && isAbstract);
if (item.getDelegate() instanceof JavaPsiClassReferenceElement) {
DefaultInsertHandler.addImportForItem(context, delegate);
}
insertParentheses(context, delegate, psiClass, !inAnonymous && isAbstract);
if (inAnonymous) {
return;
}
@@ -29,7 +29,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.util.IncorrectOperationException;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
import org.jetbrains.annotations.NotNull;
public class DefaultInsertHandler extends TemplateInsertHandler implements Cloneable {
@@ -181,10 +181,9 @@ public class DefaultInsertHandler extends TemplateInsertHandler implements Clone
JavaCompletionUtil.initOffsets(file, file.getProject(), offsetMap);
}
public static void addImportForItem(InsertionContext context, LookupElement item) throws IncorrectOperationException {
public static void addImportForItem(InsertionContext context, LookupElement item) {
PsiDocumentManager.getInstance(context.getProject()).commitAllDocuments();
int startOffset = context.getStartOffset();
PsiFile file = context.getFile();
Object o = item.getObject();
if (o instanceof PsiClass){
@@ -194,8 +193,8 @@ public class DefaultInsertHandler extends TemplateInsertHandler implements Clone
int length = lookupString.length();
final int i = lookupString.indexOf('<');
if (i >= 0) length = i;
final int newOffset = addImportForClass(file, startOffset, startOffset + length, aClass);
JavaCompletionUtil.shortenReference(file, newOffset);
addImportForClass(aClass, context, length);
JavaCompletionUtil.shortenReference(file, context.getStartOffset());
}
else if (o instanceof PsiType){
PsiType type = ((PsiType)o).getDeepComponentType();
@@ -203,7 +202,7 @@ public class DefaultInsertHandler extends TemplateInsertHandler implements Clone
PsiClass refClass = ((PsiClassType) type).resolve();
if (refClass != null){
int length = refClass.getName().length();
addImportForClass(file, startOffset, startOffset + length, refClass);
addImportForClass(refClass, context, length);
}
}
}
@@ -213,14 +212,16 @@ public class DefaultInsertHandler extends TemplateInsertHandler implements Clone
PsiClass aClass = method.getContainingClass();
if (aClass != null){
int length = method.getName().length();
addImportForClass(file, startOffset, startOffset + length, aClass);
addImportForClass(aClass, context, length);
}
}
}
}
private static int addImportForClass(PsiFile file, int startOffset, int endOffset, PsiClass aClass) throws IncorrectOperationException {
return JavaCompletionUtil.insertClassReference(aClass, file, startOffset, endOffset);
private static void addImportForClass(PsiClass aClass, InsertionContext context, int nameLength) {
context.setTailOffset(JavaCompletionUtil.insertClassReference(aClass, context.getFile(), context.getStartOffset(),
context.getStartOffset() + nameLength));
PostprocessReformattingAspect.getInstance(context.getProject()).doPostponedFormatting();
}
@@ -19,8 +19,6 @@ import com.intellij.codeInsight.AutoPopupController;
import com.intellij.codeInsight.ExpectedTypeInfo;
import com.intellij.codeInsight.ExpectedTypesProvider;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.diagnostic.LogMessageEx;
import com.intellij.diagnostic.errordialog.Attachment;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -90,8 +88,10 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE
if (fillTypeArgs) {
context.setAddCompletionChar(false);
}
if (shouldInsertParentheses(psiClass, position)) {
DefaultInsertHandler.addImportForItem(context, item);
if (shouldInsertParentheses(psiClass, file.findElementAt(context.getTailOffset() - 1))) {
if (ConstructorInsertHandler.insertParentheses(context, item, psiClass, false)) {
fillTypeArgs |= psiClass.hasTypeParameters() && PsiUtil.getLanguageLevel(file).isAtLeast(LanguageLevel.JDK_1_5);
}
@@ -101,15 +101,6 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE
AutoPopupController.getInstance(project).autoPopupParameterInfo(editor, null);
}
LOG.assertTrue(context.getTailOffset() >= 0);
String docText = context.getDocument().getText();
DefaultInsertHandler.addImportForItem(context, item);
if (context.getTailOffset() < 0) {
LOG.error(LogMessageEx.createEvent("Tail offset degraded after insertion", "start=" + context.getStartOffset(),
new Attachment(context.getFile().getViewProvider().getVirtualFile().getPath(), docText)));
}
if (annotation) {
// Check if someone inserts annotation class that require @
PsiElement elementAt = file.findElementAt(context.getStartOffset());
@@ -429,7 +429,7 @@ public class JavaCompletionUtil {
PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
boolean checkInitialized = parameters.getInvocationCount() <= 1 && call != null && PsiKeyword.SUPER.equals(call.getMethodExpression().getText());
final JavaCompletionProcessor processor = new JavaCompletionProcessor(element, elementFilter, checkAccess, checkInitialized, filterStaticAfterInstance, nameCondition);
javaReference.processVariants(processor);
final Collection<CompletionElement> plainResults = processor.getResults();
@@ -690,8 +690,8 @@ public class JavaCompletionUtil {
return null;
}
public static int insertClassReference(@NotNull PsiClass psiClass, @NotNull PsiFile file, int offset) {
return insertClassReference(psiClass, file, offset, offset);
public static void insertClassReference(@NotNull PsiClass psiClass, @NotNull PsiFile file, int offset) {
insertClassReference(psiClass, file, offset, offset);
}
public static int insertClassReference(PsiClass psiClass, PsiFile file, int startOffset, int endOffset) {
@@ -707,14 +707,14 @@ public class JavaCompletionUtil {
final PsiElement resolved = reference.resolve();
if (resolved instanceof PsiClass) {
if (((PsiClass)resolved).getQualifiedName() == null || manager.areElementsEquivalent(psiClass, resolved)) {
return startOffset;
return endOffset;
}
}
}
String name = psiClass.getName();
if (name == null) {
return startOffset;
return endOffset;
}
assert document != null;
@@ -724,7 +724,7 @@ public class JavaCompletionUtil {
PsiDocumentManager.getInstance(project).commitAllDocuments();
int newStartOffset = startOffset;
int newEndOffset = endOffset;
PsiElement element = file.findElementAt(startOffset);
if (element instanceof PsiIdentifier) {
PsiElement parent = element.getParent();
@@ -739,7 +739,13 @@ public class JavaCompletionUtil {
newElement = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(newElement);
if (newElement != null) {
newStartOffset = newElement.getTextRange().getStartOffset();
newEndOffset = newElement.getTextRange().getEndOffset();
if (newElement instanceof PsiJavaCodeReferenceElement) {
PsiReferenceParameterList parameterList = ((PsiJavaCodeReferenceElement)newElement).getParameterList();
if (parameterList != null) {
newEndOffset = parameterList.getTextRange().getStartOffset();
}
}
}
if (!staticImport &&
@@ -747,7 +753,7 @@ public class JavaCompletionUtil {
!psiClass.getManager().areElementsEquivalent(psiClass, resolveReference((PsiReference)newElement))) {
final String qName = psiClass.getQualifiedName();
if (qName != null) {
document.replaceString(newStartOffset, newElement.getTextRange().getEndOffset(), qName);
document.replaceString(newElement.getTextRange().getStartOffset(), newEndOffset, qName);
}
}
}
@@ -758,7 +764,7 @@ public class JavaCompletionUtil {
document.deleteString(toDelete.getStartOffset(), toDelete.getEndOffset());
}
return newStartOffset;
return newEndOffset;
}
@Nullable
@@ -856,9 +862,7 @@ public class JavaCompletionUtil {
//need to shorten references in type argument list
public static void shortenReference(final PsiFile file, final int offset) throws IncorrectOperationException {
final PsiDocumentManager manager = PsiDocumentManager.getInstance(file.getProject());
final Document document = manager.getDocument(file);
assert document != null;
manager.commitDocument(document);
manager.commitDocument(manager.getDocument(file));
final PsiReference ref = file.findReferenceAt(offset);
if (ref instanceof PsiJavaCodeReferenceElement) {
JavaCodeStyleManager.getInstance(file.getProject()).shortenClassReferences((PsiJavaCodeReferenceElement)ref);
@@ -21,7 +21,6 @@ import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.util.ClassConditionKey;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
import com.intellij.psi.impl.source.PsiClassReferenceType;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NonNls;
@@ -73,14 +72,11 @@ public class PsiTypeLookupItem extends LookupItem {
public void handleInsert(InsertionContext context) {
PsiElement position = context.getFile().findElementAt(context.getStartOffset());
assert position != null;
context.getDocument().insertString(context.getTailOffset(), calcGenerics(position));
DefaultInsertHandler.addImportForItem(context, this);
PostprocessReformattingAspect.getInstance(context.getProject()).doPostponedFormatting();
context.getDocument().insertString(context.getTailOffset(), calcGenerics(position));
JavaCompletionUtil.shortenReference(context.getFile(), context.getStartOffset());
int tail = context.getTailOffset();
if (tail <= 0) {
return;
}
String braces = StringUtil.repeat("[]", getBracketsCount());
Editor editor = context.getEditor();
if (!braces.isEmpty()) {