IDEA-80414 Java: selecting completion result fires WrongOffset assertion
authorpeter <peter@jetbrains.com>
Wed, 1 Feb 2012 19:31:22 +0000 (20:31 +0100)
committerpeter <peter@jetbrains.com>
Wed, 1 Feb 2012 19:56:01 +0000 (20:56 +0100)
java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java
java/java-impl/src/com/intellij/codeInsight/completion/DefaultInsertHandler.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java

index fa4ec428ed8643a6dec6f17dc71bda46640bcfa7..450c16174c22cfa7dd99017923961f928275824f 100644 (file)
@@ -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;
     }
index 0c27706ddd30f0380a94041da2a1070564b5ccf6..0f36ce3ec8fcc448cfd302fe26bdb99d3577d15e 100644 (file)
@@ -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();
   }
 
 
index 12f1ec79ad7bfa98ac908142d0fbafa1b1aa0007..08ebb822cc10f0f94eda4286e4ac8b8b47b85dd2 100644 (file)
@@ -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());
index d876f0ad9ba88929b31a19e5f58ff7f3d91603f9..c081d03ff391f2f98d0129f4ea430d021f4973e4 100644 (file)
@@ -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);
index 18050b94b35c505f5eeed839ecea3b8ca96c6a88..47fca85f1d6ad3d0e4bae4486eed0380ca00fbac 100644 (file)
@@ -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()) {