From 0d907dd377ffbaefd64c6b7f2d78b94121f80e60 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 11 Sep 2015 19:33:29 +0200 Subject: [PATCH] assert in tests that just created PsiAnchors can always be restored back fix java/drools case with classes physical for no good reason (EA-72352 - assert: SymbolCollectingProcessor$ResultWithContext.getElement) --- .../smartPointers/JavaAnchorProvider.java | 2 +- .../src/com/intellij/psi/PsiAnchor.java | 34 +++++++++++-------- .../impl/smartPointers/SelfElementInfo.java | 2 +- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/JavaAnchorProvider.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/JavaAnchorProvider.java index 17cb0d52175a..9597a68010aa 100644 --- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/JavaAnchorProvider.java +++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/JavaAnchorProvider.java @@ -26,7 +26,7 @@ import org.jetbrains.annotations.Nullable; public class JavaAnchorProvider extends SmartPointerAnchorProvider { @Override public PsiElement getAnchor(@NotNull PsiElement element) { - if (!element.getLanguage().isKindOf(JavaLanguage.INSTANCE)) { + if (!element.getLanguage().isKindOf(JavaLanguage.INSTANCE) || !element.isPhysical()) { return null; } diff --git a/platform/core-impl/src/com/intellij/psi/PsiAnchor.java b/platform/core-impl/src/com/intellij/psi/PsiAnchor.java index 51733b386fab..2d0d4e14dac9 100644 --- a/platform/core-impl/src/com/intellij/psi/PsiAnchor.java +++ b/platform/core-impl/src/com/intellij/psi/PsiAnchor.java @@ -19,6 +19,7 @@ package com.intellij.psi; import com.intellij.lang.ASTNode; import com.intellij.lang.Language; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; @@ -40,6 +41,7 @@ import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IStubFileElementType; import com.intellij.psi.util.PsiModificationTracker; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtilCore; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -51,6 +53,7 @@ import java.util.Set; * @author db */ public abstract class PsiAnchor { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.PsiAnchor"); @Nullable public abstract PsiElement retrieve(); public abstract PsiFile getFile(); @@ -59,10 +62,17 @@ public abstract class PsiAnchor { @NotNull public static PsiAnchor create(@NotNull final PsiElement element) { - if (!element.isValid()) { - throw new PsiInvalidElementAccessException(element); - } + PsiUtilCore.ensureValid(element); + PsiAnchor anchor = doCreateAnchor(element); + if (ApplicationManager.getApplication().isUnitTestMode() && !element.equals(anchor.retrieve())) { + LOG.error("Cannot restore element " + element + " of " + element.getClass() + " from anchor " + anchor); + } + return anchor; + } + + @NotNull + private static PsiAnchor doCreateAnchor(@NotNull PsiElement element) { if (element instanceof PsiFile) { VirtualFile virtualFile = ((PsiFile)element).getVirtualFile(); if (virtualFile != null) return new PsiFileReference(virtualFile, (PsiFile)element); @@ -83,7 +93,7 @@ public abstract class PsiAnchor { PsiAnchor stubRef = createStubReference(element, file); if (stubRef != null) return stubRef; - if (!element.isPhysical() && element instanceof PsiCompiledElement || element instanceof LightElement || element instanceof SyntheticElement) { + if (!element.isPhysical()) { return wrapperOrHardReference(element); } @@ -102,7 +112,10 @@ public abstract class PsiAnchor { } } - if (lang == null) lang = element.getLanguage(); + if (lang == null) { + return wrapperOrHardReference(element); + } + return new TreeRangeReference(file, textRange.getStartOffset(), textRange.getEndOffset(), element.getClass(), lang, virtualFile); } @@ -195,17 +208,8 @@ public abstract class PsiAnchor { public PsiElement retrieve() { PsiFile psiFile = getFile(); if (psiFile == null || !psiFile.isValid()) return null; - PsiElement element = psiFile.getViewProvider().findElementAt(myStartOffset, myLanguage); - if (element == null) return null; - while (!element.getClass().equals(myClass) || - element.getTextRange().getStartOffset() != myStartOffset || - element.getTextRange().getEndOffset() != myEndOffset) { - element = element.getParent(); - if (element == null || element.getTextRange() == null) return null; - } - - return element; + return SelfElementInfo.findElementInside(psiFile, myStartOffset, myEndOffset, myClass, myLanguage); } @Override diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java index 3a26df76c557..c1d58d624956 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java @@ -126,7 +126,7 @@ public class SelfElementInfo extends SmartPointerElementInfo { return restoreFileFromVirtual(getVirtualFile(), getProject(), myLanguage); } - static PsiElement findElementInside(@NotNull PsiFile file, + public static PsiElement findElementInside(@NotNull PsiFile file, int syncStartOffset, int syncEndOffset, @NotNull Class type,