mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
invalidate smart pointers when elements really become invalid (IDEA-157564)
This commit is contained in:
+20
@@ -877,6 +877,26 @@ public class SmartPsiElementPointersTest extends CodeInsightTestCase {
|
||||
return (SmartPointerEx<T>)getPointerManager().createSmartPsiElementPointer(element);
|
||||
}
|
||||
|
||||
public void testCommentingField() throws Exception {
|
||||
PsiJavaFile file = (PsiJavaFile)createFile("a.java", "class A {\n" +
|
||||
" int x;\n" +
|
||||
" int y;\n" +
|
||||
"}");
|
||||
PsiField[] fields = file.getClasses()[0].getFields();
|
||||
SmartPointerEx<PsiField> pointer0 = createPointer(fields[0]);
|
||||
SmartPointerEx<PsiField> pointer1 = createPointer(fields[1]);
|
||||
|
||||
WriteCommandAction.runWriteCommandAction(myProject, () -> {
|
||||
Document document = file.getViewProvider().getDocument();
|
||||
assert document != null;
|
||||
document.insertString(file.getText().indexOf("int"), "//");
|
||||
commitDocument(document);
|
||||
});
|
||||
|
||||
assertNull(pointer0.getElement());
|
||||
assertEquals("y", pointer1.getElement().getName());
|
||||
}
|
||||
|
||||
public void testAnchorInfoHasRange() throws Exception {
|
||||
PsiJavaFile file = (PsiJavaFile)createFile("a.java", "class C1{}");
|
||||
assertNotNull(((PsiFileImpl) file).getStubTree());
|
||||
|
||||
+9
-5
@@ -98,6 +98,13 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
|
||||
@Override
|
||||
@NotNull
|
||||
public <E extends PsiElement> SmartPsiElementPointer<E> createSmartPsiElementPointer(@NotNull E element, PsiFile containingFile) {
|
||||
return createSmartPsiElementPointer(element, containingFile, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public <E extends PsiElement> SmartPsiElementPointer<E> createSmartPsiElementPointer(@NotNull E element,
|
||||
PsiFile containingFile,
|
||||
boolean forInjected) {
|
||||
if (containingFile != null && !containingFile.isValid() || containingFile == null && !element.isValid()) {
|
||||
PsiUtilCore.ensureValid(element);
|
||||
LOG.error("Invalid element:" + element);
|
||||
@@ -108,7 +115,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
|
||||
return pointer;
|
||||
}
|
||||
|
||||
pointer = new SmartPsiElementPointerImpl<E>(myProject, element, containingFile);
|
||||
pointer = new SmartPsiElementPointerImpl<E>(myProject, element, containingFile, forInjected);
|
||||
if (containingFile != null) {
|
||||
trackPointer(pointer, containingFile.getViewProvider().getVirtualFile());
|
||||
}
|
||||
@@ -245,10 +252,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
|
||||
return;
|
||||
}
|
||||
|
||||
E newTarget = pointer.doRestoreElement();
|
||||
if (newTarget != null) {
|
||||
pointer.cacheElement(newTarget);
|
||||
}
|
||||
pointer.cacheElement(pointer.doRestoreElement());
|
||||
}
|
||||
|
||||
|
||||
|
||||
+6
-6
@@ -47,8 +47,8 @@ class SmartPsiElementPointerImpl<E extends PsiElement> implements SmartPointerEx
|
||||
private final Class<? extends PsiElement> myElementClass;
|
||||
private byte myReferenceCount = 1;
|
||||
|
||||
SmartPsiElementPointerImpl(@NotNull Project project, @NotNull E element, @Nullable PsiFile containingFile) {
|
||||
this(element, createElementInfo(project, element, containingFile), element.getClass());
|
||||
SmartPsiElementPointerImpl(@NotNull Project project, @NotNull E element, @Nullable PsiFile containingFile, boolean forInjected) {
|
||||
this(element, createElementInfo(project, element, containingFile, forInjected), element.getClass());
|
||||
}
|
||||
SmartPsiElementPointerImpl(@NotNull E element,
|
||||
@NotNull SmartPointerElementInfo elementInfo,
|
||||
@@ -142,8 +142,8 @@ class SmartPsiElementPointerImpl<E extends PsiElement> implements SmartPointerEx
|
||||
@NotNull
|
||||
private static <E extends PsiElement> SmartPointerElementInfo createElementInfo(@NotNull Project project,
|
||||
@NotNull E element,
|
||||
PsiFile containingFile) {
|
||||
SmartPointerElementInfo elementInfo = doCreateElementInfo(project, element, containingFile);
|
||||
PsiFile containingFile, boolean forInjected) {
|
||||
SmartPointerElementInfo elementInfo = doCreateElementInfo(project, element, containingFile, forInjected);
|
||||
if (ApplicationManager.getApplication().isUnitTestMode() && !element.equals(elementInfo.restoreElement())) {
|
||||
// likely cause: PSI having isPhysical==true, but which can't be restored by containing file and range. To fix, make isPhysical return false
|
||||
LOG.error("Cannot restore " + element + " of " + element.getClass() + " from " + elementInfo);
|
||||
@@ -154,7 +154,7 @@ class SmartPsiElementPointerImpl<E extends PsiElement> implements SmartPointerEx
|
||||
@NotNull
|
||||
private static <E extends PsiElement> SmartPointerElementInfo doCreateElementInfo(@NotNull Project project,
|
||||
@NotNull E element,
|
||||
PsiFile containingFile) {
|
||||
PsiFile containingFile, boolean forInjected) {
|
||||
if (element instanceof PsiDirectory) {
|
||||
return new DirElementInfo((PsiDirectory)element);
|
||||
}
|
||||
@@ -201,7 +201,7 @@ class SmartPsiElementPointerImpl<E extends PsiElement> implements SmartPointerEx
|
||||
}
|
||||
ProperTextRange proper = ProperTextRange.create(elementRange);
|
||||
|
||||
return new SelfElementInfo(project, proper, AnchorTypeInfo.obtainInfo(element, LanguageUtil.getRootLanguage(element)), containingFile, false);
|
||||
return new SelfElementInfo(project, proper, AnchorTypeInfo.obtainInfo(element, LanguageUtil.getRootLanguage(element)), containingFile, forInjected);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+1
-2
@@ -55,7 +55,6 @@ import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -199,7 +198,7 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar, ModificationT
|
||||
TextRange relevantRangeInHost = relevantRange.shiftRight(hostTextRange.getStartOffset());
|
||||
SmartPointerManagerImpl manager = (SmartPointerManagerImpl)SmartPointerManager.getInstance(myProject);
|
||||
shreds.add(new ShredImpl(manager.createSmartPsiFileRangePointer(myHostPsiFile, relevantRangeInHost, true),
|
||||
manager.createSmartPsiElementPointer(host, myHostPsiFile),
|
||||
manager.createSmartPsiElementPointer(host, myHostPsiFile, true),
|
||||
prefix, suffix, new ProperTextRange(startOffset, endOffset), false));
|
||||
return this;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user