[uast] Add UAST API for pattern matching

#IDEA-310333

GitOrigin-RevId: a469ebb49dc0c49a96a492192524709ef4a400f7
This commit is contained in:
Bart van Helvert
2024-01-26 13:05:37 +01:00
committed by intellij-monorepo-bot
parent e193e45dbf
commit 992ce073b4
4 changed files with 93 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast
import org.jetbrains.annotations.ApiStatus.Experimental
import org.jetbrains.uast.internal.acceptList
import org.jetbrains.uast.internal.log
import org.jetbrains.uast.visitor.UastTypedVisitor
import org.jetbrains.uast.visitor.UastVisitor
@Experimental
interface UBinaryExpressionWithPattern : UExpression {
/**
* Returns the operand expression.
*/
val operand: UExpression
/**
* Returns the pattern of this expression.
*/
val patternExpression: UPatternExpression?
override fun asLogString(): String = log()
override fun asRenderString(): String = "${operand.asRenderString()} is ${patternExpression?.asRenderString()}"
override fun accept(visitor: UastVisitor) {
if (visitor.visitBinaryExpressionWithPattern(this)) return
uAnnotations.acceptList(visitor)
operand.accept(visitor)
patternExpression?.accept(visitor)
visitor.afterVisitBinaryExpressionWithPattern(this)
}
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D): R = visitor.visitBinaryExpressionWithPattern(this, data)
}

View File

@@ -0,0 +1,52 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast
import org.jetbrains.annotations.ApiStatus.Experimental
import org.jetbrains.uast.internal.acceptList
import org.jetbrains.uast.internal.log
import org.jetbrains.uast.visitor.UastTypedVisitor
import org.jetbrains.uast.visitor.UastVisitor
/**
* A pattern matching expression.
* Examples (Java):
* * Type pattern: `Point p`
* * Deconstruction pattern: `Point(int x, int y)` or `Point(int _, int _)` (variables are unnamed)
* * Unnamed pattern: `Point(_, _)`
*/
@Experimental
interface UPatternExpression : UExpression {
/**
* Name of the pattern, can be null if the pattern is unnamed or no name is specified.
*/
val name: String?
/**
* The primary type reference that is checked when evaluating this pattern or null when there is none.
* * For deconstruction patterns like `Point(int x, int y)` this will be then main type `Point`.
*/
val typeReference: UTypeReferenceExpression?
/**
* The deconstructed patterns or empty if this pattern is not a deconstruction pattern.
*/
val deconstructedPatterns: List<UPatternExpression>
override fun asLogString(): String = log()
override fun asRenderString(): String {
val renderPatternList = if (deconstructedPatterns.isNotEmpty()) "(${deconstructedPatterns.joinToString { it.asRenderString() }})" else ""
val renderName = "${if (typeReference != null) " " else ""}${name ?: "_"}"
return "${typeReference?.type?.name ?: ""}$renderPatternList$renderName"
}
override fun accept(visitor: UastVisitor) {
if (visitor.visitPatternExpression(this)) return
uAnnotations.acceptList(visitor)
typeReference?.accept(visitor)
deconstructedPatterns.acceptList(visitor)
visitor.afterVisitPatternExpression(this)
}
override fun <D, R> accept(visitor: UastTypedVisitor<D, R>, data: D): R = visitor.visitPatternExpression(this, data)
}

View File

@@ -47,6 +47,8 @@ interface UastTypedVisitor<in D, out R> {
fun visitBinaryExpression(node: UBinaryExpression, data: D): R = visitPolyadicExpression(node, data)
fun visitBinaryExpressionWithType(node: UBinaryExpressionWithType, data: D): R = visitExpression(node, data)
fun visitBinaryExpressionWithPattern(node: UBinaryExpressionWithPattern, data: D): R = visitExpression(node, data)
fun visitPatternExpression(node: UPatternExpression, data: D): R = visitExpression(node, data)
fun visitParenthesizedExpression(node: UParenthesizedExpression, data: D): R = visitExpression(node, data)
// Unary operations
fun visitUnaryExpression(node: UUnaryExpression, data: D): R = visitExpression(node, data)

View File

@@ -30,6 +30,8 @@ interface UastVisitor {
fun visitCallExpression(node: UCallExpression): Boolean = visitExpression(node)
fun visitBinaryExpression(node: UBinaryExpression): Boolean = visitExpression(node)
fun visitBinaryExpressionWithType(node: UBinaryExpressionWithType): Boolean = visitExpression(node)
fun visitBinaryExpressionWithPattern(node: UBinaryExpressionWithPattern): Boolean = visitExpression(node)
fun visitPatternExpression(node: UPatternExpression) = visitExpression(node)
fun visitPolyadicExpression(node: UPolyadicExpression): Boolean = visitExpression(node)
fun visitParenthesizedExpression(node: UParenthesizedExpression): Boolean = visitExpression(node)
fun visitUnaryExpression(node: UUnaryExpression): Boolean = visitExpression(node)
@@ -88,6 +90,8 @@ interface UastVisitor {
fun afterVisitCallExpression(node: UCallExpression) = afterVisitExpression(node)
fun afterVisitBinaryExpression(node: UBinaryExpression) = afterVisitExpression(node)
fun afterVisitBinaryExpressionWithType(node: UBinaryExpressionWithType) = afterVisitExpression(node)
fun afterVisitBinaryExpressionWithPattern(node: UBinaryExpressionWithPattern) = afterVisitExpression(node)
fun afterVisitPatternExpression(node: UPatternExpression) = afterVisitExpression(node)
fun afterVisitParenthesizedExpression(node: UParenthesizedExpression) = afterVisitExpression(node)
fun afterVisitUnaryExpression(node: UUnaryExpression) = afterVisitExpression(node)
fun afterVisitPrefixExpression(node: UPrefixExpression) = afterVisitExpression(node)