correctly restore smart pointers to empty PSI elements

This commit is contained in:
peter
2015-09-01 09:59:37 +02:00
parent 2c1f8ce1ce
commit f96d8d4cd3
2 changed files with 29 additions and 0 deletions
@@ -767,4 +767,20 @@ public class SmartPsiElementPointersTest extends CodeInsightTestCase {
assertNotNull(pointer.getElement());
}
public void testPointerToEmptyElement() {
PsiFile file = configureByText(JavaFileType.INSTANCE, "class Foo {\n" +
" Test<String> test = new Test<>();\n" +
"}");
PsiJavaCodeReferenceElement ref = PsiTreeUtil.findElementOfClassAtOffset(file, file.getText().indexOf("<>"), PsiJavaCodeReferenceElement.class, false);
SmartPointerEx pointer = (SmartPointerEx)SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(
ref.getParameterList().getTypeParameterElements()[0]);
ref = null;
PlatformTestUtil.tryGcSoftlyReachableObjects();
assertNull(pointer.getCachedElement());
assertInstanceOf(pointer.getElement(), PsiTypeElement.class);
}
}
@@ -26,6 +26,7 @@ import com.intellij.openapi.util.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiDocumentManagerBase;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -133,6 +134,18 @@ public class SelfElementInfo extends SmartPointerElementInfo {
PsiElement anchor = file.getViewProvider().findElementAt(syncStartOffset, language);
if (anchor == null) return null;
PsiElement result = findParent(syncStartOffset, syncEndOffset, type, anchor);
if (result == null && syncEndOffset == syncStartOffset && anchor.getTextRange().getStartOffset() == syncEndOffset) {
anchor = PsiTreeUtil.prevLeaf(anchor, false);
if (anchor != null) {
result = findParent(syncStartOffset, syncEndOffset, type, anchor);
}
}
return result;
}
@Nullable
private static PsiElement findParent(int syncStartOffset, int syncEndOffset, @NotNull Class type, PsiElement anchor) {
TextRange range = anchor.getTextRange();
if (range.getStartOffset() != syncStartOffset) return null;