public class StubBasedPsiElementBase<T extends StubElement> extends ASTDelegatePsiElement
StubBasedPsiElementBase(ASTNode)
),
then a stub with relevant information is built from it
(IStubElementType.createStub(PsiElement, StubElement)
), and this stub is saved in the
index. Then a StubIndex query returns an instance of this element based on a stub
(created with StubBasedPsiElementBase(StubElement, IStubElementType)
constructor. To the clients, such element looks exactly
like the one created from AST, all the methods should work the same way.
Code analysis clients should be careful not to invoke methods on this class that can't be implemented using only the information from
stubs. Such case is supported: getNode()
will switch the implementation from stub to AST substrate and get this information, but
this is slow performance-wise. So stubs should be designed so that they hold all the information that's relevant for
reference resolution and other code analysis.
The subclasses should be careful not to switch to AST prematurely. For example, getParentByStub()
should be used as much
as possible in overridden getParent()
, and getStubOrPsiChildren methods should be preferred over ASTDelegatePsiElement.getChildren()
.
After switching to AST, getStub()
will return null, but getGreenStub()
can still be used to retrieve stub objects if they're needed.
The AST itself is not held on a strong reference and can be garbage-collected. This makes it possible to hold many stub-based PSI elements
in the memory at once, but results in occasionally expensive getNode()
calls that have to load and parse the AST anew.IStubElementType
,
PsiFileWithStubSupport
Iconable.IconFlags, Iconable.LastComputedIcon
Modifier and Type | Field and Description |
---|---|
static Key<java.lang.String> |
CREATION_TRACE |
static boolean |
ourTraceStubAstBinding |
FLAGS_LOCKED, ICON_PLACEHOLDER
EMPTY_NAVIGATABLE_ELEMENT_ARRAY
ARRAY_FACTORY, EMPTY_ARRAY
ICON_FLAG_IGNORE_MASK, ICON_FLAG_OPEN, ICON_FLAG_READ_STATUS, ICON_FLAG_VISIBILITY
EMPTY_NAVIGATION_ITEM_ARRAY
Constructor and Description |
---|
StubBasedPsiElementBase(ASTNode node) |
StubBasedPsiElementBase(T stub,
IElementType nodeType,
ASTNode node)
This constructor is created to allow inheriting from this class in JVM languages which doesn't support multiple constructors (e.g.
|
StubBasedPsiElementBase(T stub,
IStubElementType nodeType) |
Modifier and Type | Method and Description |
---|---|
protected java.lang.Object |
clone() |
PsiFile |
getContainingFile()
Returns the file containing the PSI element.
|
PsiElement |
getContext()
Returns the element which should be used as the parent of this element in a tree up
walk during a resolve operation.
|
IStubElementType |
getElementType() |
T |
getGreenStub()
Like
getStub() , but can return a non-null value after the element has been switched to AST. |
Language |
getLanguage()
Returns the language of the PSI element.
|
PsiManagerEx |
getManager()
Returns the PSI manager for the project to which the PSI element belongs.
|
ASTNode |
getNode()
Ensures this element is AST-based.
|
PsiElement |
getParent()
Returns the parent of the PSI element.
|
protected PsiElement |
getParentByStub()
Please consider using
getParent() instead, because this method can return different results before and after AST is loaded. |
protected PsiElement |
getParentByTree()
Deprecated.
use
getParent() instead |
Project |
getProject()
Returns the project to which the PSI element belongs.
|
<S extends StubElement,Psi extends PsiElement> |
getRequiredStubOrPsiChild(IStubElementType<S,Psi> elementType) |
T |
getStub()
Note: for most clients (where the logic doesn't crucially differ for stub and AST cases),
getGreenStub() should be preferred. |
<Psi extends PsiElement> |
getStubOrPsiChild(IStubElementType<? extends StubElement,Psi> elementType) |
<S extends StubElement,Psi extends PsiElement> |
getStubOrPsiChildren(IStubElementType<S,? extends Psi> elementType,
ArrayFactory<? extends Psi> f) |
<S extends StubElement,Psi extends PsiElement> |
getStubOrPsiChildren(IStubElementType<S,? extends Psi> elementType,
Psi [] array) |
<Psi extends PsiElement> |
getStubOrPsiChildren(TokenSet filter,
ArrayFactory<? extends Psi> f) |
<Psi extends PsiElement> |
getStubOrPsiChildren(TokenSet filter,
Psi [] array) |
protected <E extends PsiElement> |
getStubOrPsiParentOfType(java.lang.Class<E> parentClass) |
boolean |
isPhysical()
Checks if an actual source or class file corresponds to the element.
|
boolean |
isValid()
Checks if this PSI element is valid.
|
boolean |
isWritable()
Checks if the contents of the element can be modified (if it belongs to a
non-read-only source file.)
|
void |
setNode(ASTNode node)
Don't invoke this method, it's public for implementation reasons.
|
void |
setSubstrateRef(SubstrateRef substrateRef)
Don't invoke this method, it's public for implementation reasons.
|
add, addAfter, addBefore, addInternal, addRange, addRangeAfter, addRangeBefore, checkAdd, checkDelete, copy, delete, deleteChildInternal, deleteChildRange, findChildByFilter, findChildByType, findChildByType, findChildrenByType, findChildrenByType, findChildrenByType, findChildrenByType, findElementAt, findLastChildByType, findNotNullChildByType, findNotNullChildByType, getChildren, getCopyableUserData, getFirstChild, getLastChild, getNextSibling, getPrevSibling, getStartOffsetInParent, getText, getTextLength, getTextOffset, getTextRange, putCopyableUserData, replace, replaceChildInternal, subtreeChanged, textContains, textMatches, textToCharArray
accept, acceptChildren, canNavigate, canNavigateToSource, findChildByClass, findChildrenByClass, findNotNullChildByClass, findReferenceAt, getName, getNavigationElement, getOriginalElement, getPresentation, getReference, getReferences, getResolveScope, getUseScope, isEquivalentTo, navigate, notNullChild, processDeclarations, textMatches
buildRowIcon, computeBaseIcon, createLayeredIcon, getAdjustedBaseIcon, getBaseIcon, getElementIcon, getIcon, iconWithVisibilityIfNeeded, isNativeFileType, isVisibilitySupported, overlayIcons, registerIconLayer, transformFlags
changeUserMap, clearUserData, copyCopyableDataTo, copyUserDataTo, getUserData, getUserDataString, getUserMap, isUserDataEmpty, putUserData, putUserDataIfAbsent, replace, setUserMap
equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
getOwnReferences, getTextRangeInParent, toString
getUserData, putUserData
public static final Key<java.lang.String> CREATION_TRACE
public static final boolean ourTraceStubAstBinding
public StubBasedPsiElementBase(T stub, IStubElementType nodeType)
public StubBasedPsiElementBase(ASTNode node)
public StubBasedPsiElementBase(T stub, IElementType nodeType, ASTNode node)
StubBasedPsiElementBase(StubElement, IStubElementType)
and
StubBasedPsiElementBase(ASTNode)
instead.public ASTNode getNode()
getNode
in interface PsiElement
getNode
in class ASTDelegatePsiElement
getStub()
will return null.public final void setNode(ASTNode node)
public final void setSubstrateRef(SubstrateRef substrateRef)
public Language getLanguage()
PsiElement
getLanguage
in interface PsiElement
getLanguage
in class ASTDelegatePsiElement
public PsiFile getContainingFile()
PsiElement
getContainingFile
in interface PsiElement
getContainingFile
in class ASTDelegatePsiElement
public boolean isWritable()
PsiElement
isWritable
in interface PsiElement
isWritable
in class PsiElementBase
public boolean isValid()
PsiElement
PsiDocumentManager.commitDocument(com.intellij.openapi.editor.Document)
).
(In this case an attempt to change PSI will result in an exception).
Any access to invalid elements results in PsiInvalidElementAccessException
.
Once invalid, elements can't become valid again.
Elements become invalid in following cases:
PsiElement.delete()
)isValid
in interface PsiElement
isValid
in class PsiElementBase
PsiUtilCore.ensureValid(PsiElement)
public PsiManagerEx getManager()
PsiElement
getManager
in interface PsiElement
getManager
in class ASTDelegatePsiElement
public Project getProject()
PsiElement
getProject
in interface PsiElement
getProject
in class PsiElementBase
public boolean isPhysical()
PsiElement
PsiDocumentManager.getDocument(PsiFile)
returns null for non-physical elements.
Not to be confused with FileViewProvider.isPhysical()
.isPhysical
in interface PsiElement
isPhysical
in class PsiElementBase
public PsiElement getContext()
PsiElement
getParent()
,
but the context can be overridden for some elements like code fragments (see
JavaCodeFragmentFactory.createCodeBlockCodeFragment(String, PsiElement, boolean)
).getContext
in interface PsiElement
getContext
in class PsiElementBase
protected final PsiElement getParentByStub()
getParent()
instead, because this method can return different results before and after AST is loaded.@Deprecated protected final PsiElement getParentByTree()
getParent()
insteadpublic PsiElement getParent()
PsiElement
public IStubElementType getElementType()
public T getStub()
getGreenStub()
should be preferred.getNode()
on this or any other element
in the containing file.public final T getGreenStub()
getStub()
, but can return a non-null value after the element has been switched to AST. Can be used
to retrieve the information which is cheaper to get from a stub than by tree traversal.PsiFileImpl#getGreenStub()
public <Psi extends PsiElement> Psi getStubOrPsiChild(IStubElementType<? extends StubElement,Psi> elementType)
public <S extends StubElement,Psi extends PsiElement> Psi getRequiredStubOrPsiChild(IStubElementType<S,Psi> elementType)
public <S extends StubElement,Psi extends PsiElement> Psi [] getStubOrPsiChildren(IStubElementType<S,? extends Psi> elementType, Psi [] array)
public <S extends StubElement,Psi extends PsiElement> Psi [] getStubOrPsiChildren(IStubElementType<S,? extends Psi> elementType, ArrayFactory<? extends Psi> f)
public <Psi extends PsiElement> Psi [] getStubOrPsiChildren(TokenSet filter, Psi [] array)
public <Psi extends PsiElement> Psi [] getStubOrPsiChildren(TokenSet filter, ArrayFactory<? extends Psi> f)
protected <E extends PsiElement> E getStubOrPsiParentOfType(java.lang.Class<E> parentClass)
protected java.lang.Object clone()
clone
in class UserDataHolderBase