A symbol is a semantic element in some model, e.g., language or framework model.
The IntelliJ Platform uses
Symbol to represent symbols, and
Symbol serves as a link between Platform APIs, such as navigation, finding usages, or renaming. This API allows implementing the same functionalities as in the References and Resolve mechanism, but it is a more abstract concept not limited to connecting only PSI elements. The platform obtains the target symbol from a declaration or by resolving a reference and then uses it to perform an action. The
PsiElement is considered as an element in the source tree (enhanced
Symbol decouples semantic actions from PSI.
Symbol is not required to be backed by a
PsiElement, and it is incorrect to try to obtain the
PsiElement from a
Symbol is not required to be bound to a
Project as well, meaning the same instance might be shared between projects.
Java local variable is a symbol in Java language model, it's backed by a
Compiled class is a symbol in JVM model, it's backed by JDK library stubs, and it's not bound to any project.
Spring Bean is a symbol in Spring framework model, it's defined on-the-fly by framework support (not backed by a
PsiElement) and bound to a
Database column is a symbol defined by data source (not backed by a
PsiElement) and not bound to a
Projectsince database elements might be shared between projects.
Symbol instance is expected to stay valid within a single read action, which means it's safe to pass the instance to different APIs. A
Symbol instance should not be referenced between read actions. One should create a pointer via
Symbol.createPointer() in the current read action, and then call
Pointer.dereference() to obtain a
Symbol instance in the subsequent read action.