* For light elements, may return {@code null}.
*
* @return the element in the file copy corresponding to this element.
*/
PsiElement copy();
/**
* Adds a child to this PSI element.
*
* @param element the child element to add.
* @return the element which was actually added (either {@code element} or its copy).
* @throws IncorrectOperationException if the modification is not supported or not possible for some reason.
*/
PsiElement add(@NotNull PsiElement element) throws IncorrectOperationException;
/**
* Adds a child to this PSI element, before the specified anchor element.
*
* @param element the child element to add.
* @param anchor the anchor before which the child element is inserted (must be a child of this PSI element)
* @return the element which was actually added (either {@code element} or its copy).
* @throws IncorrectOperationException if the modification is not supported or not possible for some reason.
*/
PsiElement addBefore(@NotNull PsiElement element, @Nullable PsiElement anchor) throws IncorrectOperationException;
/**
* Adds a child to this PSI element, after the specified anchor element.
*
* @param element the child element to add.
* @param anchor the anchor after which the child element is inserted (must be a child of this PSI element)
* @return the element which was actually added (either {@code element} or its copy).
* @throws IncorrectOperationException if the modification is not supported or not possible for some reason.
*/
PsiElement addAfter(@NotNull PsiElement element, @Nullable PsiElement anchor) throws IncorrectOperationException;
/**
* Checks if it is possible to add the specified element as a child to this element,
* and throws an exception if the add is not possible. Does not actually modify anything.
*
* @param element the child element to check the addition possibility.
* @throws IncorrectOperationException if the modification is not supported or not possible for some reason.
* @deprecated not all PSI implementations implement this method correctly.
*/
@Deprecated
void checkAdd(@NotNull PsiElement element) throws IncorrectOperationException;
/**
* Adds a range of elements as children to this PSI element.
*
* @param first the first child element to add.
* @param last the last child element to add (must have the same parent as {@code first})
* @return the first child element which was actually added (either {@code first} or its copy).
* @throws IncorrectOperationException if the modification is not supported or not possible for some reason.
*/
PsiElement addRange(PsiElement first, PsiElement last) throws IncorrectOperationException;
/**
* Adds a range of elements as children to this PSI element, before the specified anchor element.
*
* @param first the first child element to add.
* @param last the last child element to add (must have the same parent as {@code first})
* @param anchor the anchor before which the child element is inserted (must be a child of this PSI element)
* @return the first child element which was actually added (either {@code first} or its copy).
* @throws IncorrectOperationException if the modification is not supported or not possible for some reason.
*/
PsiElement addRangeBefore(@NotNull PsiElement first, @NotNull PsiElement last, PsiElement anchor) throws IncorrectOperationException;
/**
* Adds a range of elements as children to this PSI element, after the specified anchor element.
*
* @param first the first child element to add.
* @param last the last child element to add (must have the same parent as {@code first})
* @param anchor the anchor after which the child element is inserted (must be a child of this PSI element)
* @return the first child element which was actually added (either {@code first} or its copy).
* @throws IncorrectOperationException if the modification is not supported or not possible for some reason.
*/
PsiElement addRangeAfter(PsiElement first, PsiElement last, PsiElement anchor) throws IncorrectOperationException;
/**
* Deletes this PSI element from the tree.
*
* @throws IncorrectOperationException if the modification is not supported
* or not possible for some reason (for example, the file containing the element is read-only).
*/
void delete() throws IncorrectOperationException;
/**
* Checks if it is possible to delete the specified element from the tree,
* and throws an exception if the addition is not possible. Does not actually modify anything.
*
* @throws IncorrectOperationException if the modification is not supported or not possible for some reason.
* @deprecated not all PSI implementations implement this method correctly.
*/
@Deprecated
void checkDelete() throws IncorrectOperationException;
/**
* Deletes a range of children of this PSI element from the tree.
*
* @param first the first child to delete (must be a child of this PSI element)
* @param last the last child to delete (must be a child of this PSI element)
* @throws IncorrectOperationException if the modification is not supported or not possible for some reason.
*/
void deleteChildRange(PsiElement first, PsiElement last) throws IncorrectOperationException;
/**
* Replaces this PSI element (along with all its children) with another element
* (along with the children).
*
* @param newElement the element to replace this element with.
* @return the element which was actually inserted in the tree (either {@code newElement} or its copy)
* @throws IncorrectOperationException if the modification is not supported or not possible for some reason.
*/
PsiElement replace(@NotNull PsiElement newElement) throws IncorrectOperationException;
/**
* Checks if this PSI element is valid. Valid elements and their hierarchy members
* can be accessed for reading and writing. Valid elements can still correspond to
* underlying documents whose text is different, when those documents have been changed
* and not yet committed ({@link PsiDocumentManager#commitDocument(com.intellij.openapi.editor.Document)}).
* (In this case an attempt to change PSI will result in an exception).
*
* Most method calls on invalid PSI result in {@link PsiInvalidElementAccessException}.
* Once invalid, elements can't become valid again.
* Elements become invalid in following cases:
*
* On the other hand {@code "bar"} literal in {@code new File("bar")} is a string literal, * and from Java language perspective it has no references, * but the framework support "knows" that this literal contains the reference to a file. * These are external references. *
* The contents of the returned collection are copied after the method returns, * the platform doesn't store or modify the returned collection. * * @return collection of references from this element, or empty collection if there are no such references * @see com.intellij.model.psi.PsiExternalReferenceHost * @see com.intellij.model.psi.PsiSymbolReferenceService#getReferences(PsiElement) */ @Experimental default @NotNull Collection extends @NotNull PsiSymbolReference> getOwnReferences() { return Collections.emptyList(); } /** * Returns the reference from this PSI element to another PSI element (or elements), if one exists. * If the element has multiple associated references (see {@link #getReferences()} * for an example), returns the first associated reference. * * @return the reference instance, or null if the PSI element does not have any * associated references. * @see com.intellij.psi.search.searches.ReferencesSearch */ @Nullable @Contract(pure=true) PsiReference getReference(); /** * Returns all references from this PSI element to other PSI elements. An element can * have multiple references when, for example, the element is a string literal containing * multiple sub-strings which are valid full-qualified class names. If an element * contains only one text fragment which acts as a reference but the reference has * multiple possible targets, {@link PsiPolyVariantReference} should be used instead * of returning multiple references. * * Actually, it's preferable to call {@link PsiReferenceService#getReferences} instead * as it allows adding references by plugins when the element implements {@link ContributedReferenceHost}. * * @return the array of references, or an empty array if the element has no associated * references. * @see PsiReferenceService#getReferences * @see com.intellij.psi.search.searches.ReferencesSearch */ @Contract(pure=true) PsiReference @NotNull [] getReferences(); /** * Returns a copyable user data object attached to this element. * * @param key the key for accessing the user data object. * @return the user data object, or null if no such object is found in the current element. * @see #putCopyableUserData(Key, Object) */ @Nullable @Contract(pure = true) T getCopyableUserData(@NotNull Key key); /** * Attaches a copyable user data object to this element. Copyable user data objects are copied * when the PSI elements are copied. * * @param key the key for accessing the user data object. * @param value the user data object to attach. * @see #getCopyableUserData(Key) */ void putCopyableUserData(@NotNull Key key, @Nullable T value); /** * Passes the declarations contained in this PSI element and its children * for processing to the specified scope processor. * * @param processor the processor receiving the declarations. * @param lastParent the child of this element has been processed during the previous * step of the tree up walk (declarations under this element do not need * to be processed again) * @param place the original element from which the tree walk-up was initiated. * @return true if the declaration processing should continue or false if it should be stopped. */ boolean processDeclarations(@NotNull PsiScopeProcessor processor, @NotNull ResolveState state, @Nullable PsiElement lastParent, @NotNull PsiElement place); /** * Returns the element which should be used as the parent of this element in a tree up * walk during a resolve operation. For most elements, this returns {@code getParent()}, * but the context can be overridden for some elements like code fragments (see * {@link JavaCodeFragmentFactory#createCodeBlockCodeFragment(String, PsiElement, boolean)}). * * @return the resolve context element. */ @Nullable @Contract(pure=true) PsiElement getContext(); /** * Checks if an actual source or class file corresponds to the element. Non-physical elements include, * for example, PSI elements created for the watch expressions in the debugger. * Non-physical elements do not generate tree change events. * Also, {@link PsiDocumentManager#getDocument(PsiFile)} returns null for non-physical elements. * Not to be confused with {@link FileViewProvider#isPhysical()}. * * @return true if the element is physical, false otherwise. */ @Contract(pure=true) boolean isPhysical(); /** * Returns the scope in which the declarations for the references in this PSI element are searched. * * @return the resolve scope instance. */ @NotNull @Contract(pure=true) GlobalSearchScope getResolveScope(); /** * Returns the scope in which references to this element are searched. * * @return the search scope instance. * @see com.intellij.psi.search.PsiSearchHelper#getUseScope(PsiElement) */ @NotNull @Contract(pure=true) SearchScope getUseScope(); /** * Returns the AST node corresponding to the element. * * @return the AST node instance. */ @Contract(pure=true) ASTNode getNode(); /** * toString() should never be presented to the user. */ @Override @NonNls @Contract(pure=true) String toString(); /** * This method shouldn't be called by clients directly, because there are no guarantees of it being symmetric. * It's called by {@link PsiManager#areElementsEquivalent(PsiElement, PsiElement)} internally, which clients should invoke instead. * * Implementations of this method should return {@code true} if the parameter is resolve-equivalent to {@code this}, i.e. it represents * the same entity from the language perspective. See also {@link PsiManager#areElementsEquivalent(PsiElement, PsiElement)} documentation. */ @Contract(pure=true) boolean isEquivalentTo(PsiElement another);