Resolving Symbols
Symbol resolution answers "what declaration does this PSI element refer to?". The result is the literal target of the element — a class, function, property, type parameter, package, or any other declaration. Read Resolution Fundamentals first if you have not.
Entry points
For a given resolvable PSI element, prefer the specialized form — an extension on the concrete PSI type with a precisely typed return value:
When the PSI type is unknown, fall back to the generic form on KtResolvable via a safe cast:
resolveSymbol() returns the single resolved symbol, or null if resolution failed or produced more than one candidate. resolveSymbols() returns every resolved symbol — useful when ambiguity is acceptable. For the richest form (success / error / diagnostic / candidate symbols), use tryResolveSymbols() and the KaSymbolResolutionAttempt hierarchy.
Specialized methods
Each row below is an extension defined on the listed PSI type. The return type is precisely the kind of symbol that the element can refer to.
Symbols of callables and constructors
PSI element | Returns |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Symbols of classifiers and labels
PSI element | Returns |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
KtUserType does not have a specialized resolveSymbol() extension. It implements KtResolvable, so the generic form applies — with the broader return type KaSymbol?. See the Type-side resolution section below for the user-type subtleties (including resolution to a KaPackageSymbol for qualified-path prefixes).
A few of these also expose a call counterpart (for example KtCallElement → resolveCall(): KaFunctionCall<*>?). See Resolving Calls for the call-side specializations.
resolveSymbol shows the literal target
The defining principle of symbol resolution: the symbol is what the element itself refers to, not what is invoked at that site. The clearest illustration is KtNameReferenceExpression.
For MyClass(), the name reference MyClass literally points to the class, so resolveSymbol() returns a KaClassLikeSymbol for MyClass. The constructor that is actually invoked only shows up in call resolution, because invoking a class means calling its constructor.
A KtNameReferenceExpression can also resolve to a type, not just a callable — this is why the generic return type is KaSymbol? rather than KaCallableSymbol?.
Type-side resolution
Symbol resolution is the only resolution flavor that applies to types. KtTypeReference, KtUserType, KtNullableType, KtFunctionType, and KtClassLiteralExpression all support resolveSymbol() but no resolveCall(). Of these, only KtUserType lacks a specialized return type — it reuses the generic KtResolvable.resolveSymbol().
For a well-formed type the result is a KaClassifierSymbol. For a KtFunctionType, the result is the corresponding FunctionN/SuspendFunctionN class — the return type is narrowed to KaClassSymbol?.
KtUserType delegates to its inner simple-name reference, so calling resolveSymbol() on a user type returns the same symbol as resolving the inner expression. One subtlety, documented as an Analysis API Resolver Note on KtUserType itself:
A KtUserType may also resolve to a KaPackageSymbol when it appears as the package qualifier of a fully qualified nested type. In that case the user type is not a classifier reference itself but a package portion of one:
When walking type references, expect KaPackageSymbol and handle it explicitly.
Plain form vs try form
Use resolveSymbol()/resolveSymbols() when you only care about a valid result and want failed/ambiguous resolutions to be silently dropped. This is the right default for inspections that must not produce false positives.
Use tryResolveSymbols() when you want everything the compiler considered. The result is a KaSymbolResolutionAttempt carrying success, error, or compound-error variants — with diagnostics and candidate symbols. See KaSymbolResolutionAttempt for the full breakdown.
The two helpers KaSymbolResolutionAttempt.symbols and KaSymbolResolutionAttempt.successfulSymbols cover the most common access patterns without forcing pattern matching on the sealed hierarchy.