KtPsiUtil¶
open class KtPsiUtil
A collection of static helper methods for working with the Kotlin PSI.
The utilities here cover common low-level operations such as unwrapping parenthesized expressions (deparenthesize), inspecting names and identifiers, and testing structural properties of elements (for example, whether a declaration is local). This class is not instantiable.
Types¶
KtExpressionWrapper¶
interface KtExpressionWrapper
An element that wraps a base expression, such as a parenthesized or annotated expression.
Companion functions¶
ascendIfPropertyAccessor¶
open fun ascendIfPropertyAccessor(element: PsiElement): PsiElement
If element is a property accessor, returns its owning property; otherwise returns element unchanged.
checkVariableDeclarationInBlock¶
open fun checkVariableDeclarationInBlock(@NotNull block: KtBlockExpression, @NotNull varName: String): Boolean
Returns true if block contains a variable declaration named varName.
checkWhenExpressionHasSingleElse¶
open fun checkWhenExpressionHasSingleElse(@NotNull whenExpression: KtWhenExpression): Boolean
Returns true if whenExpression has exactly one else branch.
deparenthesize¶
@Nullable
open fun deparenthesize(@Nullable expression: KtExpression): KtExpression
Recursively unwraps parentheses, labels, and annotations from the given expression.
@Nullable
open fun deparenthesize(@Nullable expression: KtExpression, keepAnnotations: Boolean): KtExpression
Recursively unwraps parentheses and labels (and annotations unless keepAnnotations is true) from the given expression, returning the innermost wrapped expression.
deparenthesizeOnce¶
@Nullable
open fun deparenthesizeOnce(@Nullable expression: KtExpression): KtExpression
Unwraps a single layer of parentheses, label, or annotation from the given expression.
@Nullable
open fun deparenthesizeOnce(@Nullable expression: KtExpression, keepAnnotations: Boolean): KtExpression
Unwraps a single layer of parentheses or label (and annotation unless keepAnnotations is true) from the given expression.
findChildByType¶
@Nullable
open fun findChildByType(@NotNull element: PsiElement, @NotNull type: IElementType): PsiElement
Returns the first direct child of element with the given node type, or null if there is none.
findRootExpressions¶
@NotNull
open fun findRootExpressions(@NotNull unreachableElements: Collection<KtElement>): Set<KtElement>
Returns the subset of unreachableElements that are not contained within any other element of the set.
getClassIfParameterIsProperty¶
@Nullable
open fun getClassIfParameterIsProperty(@NotNull ktParameter: KtParameter): KtClassOrObject
If ktParameter is a primary-constructor val/var property parameter, returns the class or object that declares it; otherwise returns null.
getDirectParentOfTypeForBlock¶
@Nullable
open fun <T : PsiElement?> getDirectParentOfTypeForBlock(@NotNull block: KtBlockExpression, @NotNull aClass: Class<T>): T
Returns the enclosing element of type aClass for which block is a direct body (an if branch, a when entry, a lambda body, or a try/catch body), or null otherwise.
getEnclosingElementForLocalDeclaration¶
@Nullable
open fun getEnclosingElementForLocalDeclaration(@NotNull declaration: KtDeclaration): KtElement
Returns the innermost element that scopes declaration as a local declaration (a block, parameter, and so on), or null if the declaration is not local. See getEnclosingElementForLocalDeclaration with skipParameters.
@Nullable
open fun getEnclosingElementForLocalDeclaration(@NotNull declaration: KtDeclaration, skipParameters: Boolean): KtElement
Returns the innermost element that scopes declaration as a local declaration, or null if it is not local. When skipParameters is true, type and value parameters delegate to their owning declaration.
getExpressionOrLastStatementInBlock¶
@Nullable
open fun getExpressionOrLastStatementInBlock(@Nullable expression: KtExpression): KtExpression
Returns the last statement of expression if it is a block, otherwise expression itself.
getLastChildByType¶
@SafeVarargs
open fun <T : PsiElement?> getLastChildByType(@NotNull root: PsiElement, @NotNull elementTypes: Array<Class<out T>>): T
Returns the last direct child of root whose type is one of elementTypes, or null if there is none.
getLastElementDeparenthesized¶
@Nullable
open fun getLastElementDeparenthesized(@Nullable expression: KtExpression, @NotNull statementFilter: StatementFilter): KtExpression
Deparenthesizes expression and, if it is a block, recurses into the block's last statement (respecting statementFilter), returning the innermost "result" expression.
getLastReference¶
@Nullable
open fun getLastReference(@NotNull importedReference: KtExpression): KtSimpleNameExpression
Returns the last (rightmost) simple-name reference of the given qualified importedReference, or null.
getLastStatementInABlock¶
@Nullable
open fun getLastStatementInABlock(@Nullable blockExpression: KtBlockExpression): KtExpression
Returns the last statement of the given block, or null if the block is null or empty.
getNullableText¶
@Nullable
open fun getNullableText(@Nullable element: PsiElement): String
Returns the text of element, or null if element is null.
getOperationToken¶
@Nullable
open fun getOperationToken(@NotNull expression: KtOperationExpression): KtToken
Returns the operation token of expression (for example, PLUS), or null if unavailable.
getOutermostClassOrObject¶
@NotNull
open fun getOutermostClassOrObject(@NotNull classOrObject: KtClassOrObject): KtClassOrObject
Returns the outermost class that lexically encloses (and includes) the given class.
Starting from classOrObject, this repeatedly ascends to the enclosing class and returns the last one reached — the top of the class-nesting chain.
The walk stops as soon as a declaration has no enclosing class; in particular:
- a top-level class is returned unchanged;
- a nested or inner class resolves to the top-level class that contains it;
- a local class (declared inside a code block) is returned unchanged, and the walk never crosses out of a local class into its surrounding block — so a class nested inside a local class resolves to that local class rather than to any top-level declaration.
Note: a class declared inside a
companion { }block (which is invalid code) is treated as nested directly in the class that owns the block. Example:
For these declarations, getOutermostClassOrObject(nested) returns top, while calls for local and insideLocal both return local. The search does not cross the local-class boundary.
Return
the outermost enclosing class; never null — at minimum classOrObject itself
Parameters
- classOrObject: the class to start the search from
getOutermostDescendantElement¶
@Nullable
open fun getOutermostDescendantElement(
@Nullable root: PsiElement,
first: Boolean,
@NotNull predicate: Predicate<KtElement>
): KtElement
Traverses root and its subtree, collecting the outermost elements that satisfy predicate without descending into a match. Returns the first or last match in depth-first traversal order, as selected by first, or null if there is none. If root matches, it is the only result.
Example:
Given the containing file, the following searches return First and Second, respectively:
KtElement firstClass = getOutermostDescendantElement(file, true, element -> element instanceof KtClass);
KtElement lastClass = getOutermostDescendantElement(file, false, element -> element instanceof KtClass);
Nested is not considered because the traversal does not descend into First after it matches.
getOutermostParent¶
@Nullable
open fun getOutermostParent(
@NotNull element: PsiElement,
@NotNull upperBound: PsiElement,
strict: Boolean
): PsiElement
Returns the outermost ancestor of element that is still a direct child of upperBound, or null. When strict is false, element itself is considered.
getPackageName¶
@Nullable
open fun getPackageName(@NotNull element: KtElement): String
Returns the dot-separated package name of the file containing element, or null if unavailable.
getParentCallIfPresent¶
@Nullable
open fun getParentCallIfPresent(@NotNull expression: KtExpression): KtExpression
Returns the nearest enclosing call-like expression that expression is an operand or argument of, looking through parentheses, casts, argument lists, lambdas, and labels, or null if there is none.
Example:
For the first statement, calling this method on the value expression returns the consume(...) call because casts and parentheses are skipped. For the second statement, calling it on left returns the nearer binary expression left + right rather than the outer consume(...) call.
getPreviousWord¶
@Nullable
open fun getPreviousWord(@NotNull element: PsiElement, @NotNull word: String): PsiElement
Returns the previous leaf if it is the identifier word (skipping whitespace and comments), or null.
getScript¶
@Nullable
open fun getScript(@NotNull namedDeclaration: KtDeclaration): KtScript
Returns the script this declaration is a top-level member of, or null if it is not in a script.
getText¶
Returns the text of element, or an empty string if element is null.
getTopmostParentOfTypes¶
@Nullable
@SafeVarargs
@Contract(value = "null, _ -> null")
open fun getTopmostParentOfTypes(@Nullable element: PsiElement, @NotNull parentTypes: Array<Class<out PsiElement>>): PsiElement
Returns the topmost ancestor of element (or the enclosing file) whose type is one of parentTypes, or null if there is none.
isAbstract¶
open fun isAbstract(@NotNull declaration: KtDeclarationWithBody): Boolean
Returns true if declaration has no body expression. This is a syntactic check; it does not inspect the abstract modifier or determine whether the declaration is semantically abstract.
isAssignment¶
open fun isAssignment(@NotNull element: PsiElement): Boolean
Returns true if element is an assignment (= or an augmented assignment such as +=).
isBooleanConstant¶
open fun isBooleanConstant(@Nullable condition: KtExpression): Boolean
Returns true if condition is a boolean literal (true or false).
isCast¶
open fun isCast(@NotNull expression: KtBinaryExpressionWithTypeRHS): Boolean
Returns true if expression is a cast, whether safe (as?) or unsafe (as).
isDeprecated¶
open fun isDeprecated(@NotNull owner: KtModifierListOwner): Boolean
Returns true if owner is syntactically annotated with @Deprecated (by short name only).
isFalseConstant¶
open fun isFalseConstant(@Nullable condition: KtExpression): Boolean
Returns true if condition is the boolean literal false.
isInComment¶
open fun isInComment(element: PsiElement): Boolean
Returns true if element is a comment or is inside a KDoc comment.
isComment does not recognize elements inside a comment. KDoc tokens cannot be added to the general comment token set because the parser ignores every token in that set.
isInOrNotInOperation¶
open fun isInOrNotInOperation(@NotNull binaryExpression: KtBinaryExpression): Boolean
Returns true if binaryExpression is an in or !in membership check.
isLabeledFunctionLiteral¶
open fun isLabeledFunctionLiteral(@NotNull functionLiteral: KtFunctionLiteral): Boolean
Returns true if functionLiteral's enclosing lambda expression carries a label.
isLabelIdentifierExpression¶
open fun isLabelIdentifierExpression(element: PsiElement): Boolean
Returns true if element is a label reference expression.
isLHSOfDot¶
open fun isLHSOfDot(@NotNull expression: KtExpression): Boolean
Returns true if expression is on the left-hand side (the receiver) of a qualified ./?. expression.
isLocal¶
open fun isLocal(@NotNull declaration: KtDeclaration): Boolean
Returns true if declaration is local (declared inside a function body or other local scope).
isNotInOperation¶
open fun isNotInOperation(@NotNull binaryExpression: KtBinaryExpression): Boolean
Returns true if binaryExpression is a !in (not-in) membership check.
isNullConstant¶
open fun isNullConstant(@NotNull expression: KtExpression): Boolean
Returns true if expression (after deparenthesizing) is the null literal.
isOrdinaryAssignment¶
open fun isOrdinaryAssignment(@NotNull element: PsiElement): Boolean
Returns true if element is a plain assignment (=), excluding augmented assignments.
isRemovableVariableDeclaration¶
open fun isRemovableVariableDeclaration(@NotNull declaration: KtDeclaration): Boolean
Returns true if declaration has a PSI form supported by unused-variable cleanup: a property can be removed and a destructuring entry can be replaced with _. This is a syntactic classification; it does not determine whether the declaration is unused or whether removing it preserves behavior.
isSafeCast¶
open fun isSafeCast(@NotNull expression: KtBinaryExpressionWithTypeRHS): Boolean
Returns true if expression is a safe cast (as?).
isScriptDeclaration¶
open fun isScriptDeclaration(@NotNull namedDeclaration: KtDeclaration): Boolean
Returns true if namedDeclaration is a top-level declaration of a script.
isSelectorInQualified¶
open fun isSelectorInQualified(@NotNull nameExpression: KtSimpleNameExpression): Boolean
Returns true if nameExpression is the selector of a qualified expression or qualified user type.
isStatement¶
open fun isStatement(@NotNull element: PsiElement): Boolean
Returns true if element appears in a statement position (its parent is a statement container).
isStatementContainer¶
open fun isStatementContainer(@Nullable container: PsiElement): Boolean
Returns true if container is an element whose children are statements (a block, control-structure body, or when entry).
isTrait¶
open fun isTrait(@NotNull classOrObject: KtClassOrObject): Boolean
Returns true if classOrObject is an interface.
isTrueConstant¶
open fun isTrueConstant(@Nullable condition: KtExpression): Boolean
Returns true if condition is the boolean literal true.
isUnsafeCast¶
open fun isUnsafeCast(@NotNull expression: KtBinaryExpressionWithTypeRHS): Boolean
Returns true if expression is an unsafe cast (as).
prevLeafIgnoringWhitespaceAndComments¶
@Nullable
open fun prevLeafIgnoringWhitespaceAndComments(@NotNull element: PsiElement): PsiElement
Returns the previous leaf before element, skipping whitespace and comments, or null.
safeDeparenthesize¶
@NotNull
open fun safeDeparenthesize(@NotNull expression: KtExpression): KtExpression
@NotNull
open fun safeDeparenthesize(@NotNull expression: KtExpression, keepAnnotations: Boolean): KtExpression
Like deparenthesize, but returns expression itself if there is nothing to unwrap.
safeName¶
Returns name as a Name, or the special "no name provided" name if name is null.
skipSiblingsBackwardByPredicate¶
@Nullable
open fun skipSiblingsBackwardByPredicate(@Nullable element: PsiElement, elementsToSkip: Predicate<PsiElement>): PsiElement
Returns the first preceding sibling of element not matched by elementsToSkip, or null.
skipTrailingWhitespacesAndComments¶
@Nullable
open fun skipTrailingWhitespacesAndComments(@Nullable element: PsiElement): PsiElement
Returns the first following sibling of element that is neither whitespace nor a comment, or null.
unquoteIdentifier¶
@NotNull
open fun unquoteIdentifier(@NotNull quoted: String): String
Removes surrounding backticks from a backtick-quoted identifier, returning quoted unchanged if it has none.
unquoteIdentifierOrFieldReference¶
@NotNull
open fun unquoteIdentifierOrFieldReference(@NotNull quoted: String): String
Like unquoteIdentifier, but also handles a leading $ field-reference prefix.
visitChildren¶
Dispatches each direct KtElement child of the given element to the visitor.