[uast] Support try-with-resource expressions in Java

#IDEA-337821 Fixed

GitOrigin-RevId: c17644363e2d00219f5ab08a547ad5532f24974b
This commit is contained in:
Bart van Helvert
2023-11-15 15:46:19 +01:00
committed by intellij-monorepo-bot
parent 3ab222dfe6
commit 159cf612e9
10 changed files with 72 additions and 13 deletions

View File

@@ -32,7 +32,10 @@ class KotlinUTryExpression(
}
}
override val resourceVariables: List<UVariable>
@Deprecated("This API doesn't support resource expression", replaceWith = ReplaceWith("resources"))
override val resourceVariables: List<UVariable> get() = resources.filterIsInstance<UVariable>()
override val resources: List<UAnnotated>
get() = emptyList()
override val hasResources: Boolean

View File

@@ -34,8 +34,16 @@ interface UTryExpression : UExpression {
val hasResources: Boolean
/**
* Returns the list of resource variables declared in this expression, or an empty list if this expression is not a `try-with-resources` expression.
* Returns the list of resource variables or expressions declared in this expression, or an empty list if this expression is not a
* `try-with-resources` expression.
*/
val resources: List<UAnnotated> get() = emptyList()
/**
* Returns the list of resource variables declared in this expression, or an empty list if this expression is not a `try-with-resources`
* expression.
*/
@Deprecated("This API doesn't support resource expression", ReplaceWith("resources"))
val resourceVariables: List<UVariable>
/**
@@ -66,7 +74,7 @@ interface UTryExpression : UExpression {
override fun accept(visitor: UastVisitor) {
if (visitor.visitTryExpression(this)) return
uAnnotations.acceptList(visitor)
resourceVariables.acceptList(visitor)
resources.acceptList(visitor)
tryClause.accept(visitor)
catchClauses.acceptList(visitor)
finallyClause?.accept(visitor)
@@ -78,9 +86,9 @@ interface UTryExpression : UExpression {
override fun asRenderString(): String = buildString {
append("try ")
if (hasResources) {
if (resources.isNotEmpty()) {
append("(")
append(resourceVariables.joinToString("\n") { it.asRenderString() })
append(resources.joinToString("\n") { it.asRenderString() })
append(")")
}
appendLine(tryClause.asRenderString().trim('\n', '\r'))

View File

@@ -315,6 +315,10 @@ internal object JavaConverter {
override fun visitReferenceParameterList(list: PsiReferenceParameterList) {
result = true
}
override fun visitResourceList(resourceList: PsiResourceList) {
result = true
}
}
element.accept(visitor)

View File

@@ -15,7 +15,7 @@ class JavaUTryExpression(
private val tryClausePart = UastLazyPart<UExpression>()
private val catchClausesPart = UastLazyPart<List<UCatchClause>>()
private val finallyClausePart = UastLazyPart<UBlockExpression?>()
private val resourceVariablesPart = UastLazyPart<List<UVariable>>()
private val resourceVariablesPart = UastLazyPart<List<UAnnotated>>()
override val tryClause: UExpression
get() = tryClausePart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.tryBlock, this) }
@@ -26,12 +26,18 @@ class JavaUTryExpression(
override val finallyClause: UBlockExpression?
get() = finallyClausePart.getOrBuild { sourcePsi.finallyBlock?.let { JavaConverter.convertBlock(it, this) } }
override val resourceVariables: List<UVariable>
@Deprecated("This API doesn't support resource expression", replaceWith = ReplaceWith("resources"))
override val resourceVariables: List<UVariable> get() = resources.filterIsInstance<UVariable>()
override val resources: List<UAnnotated>
get() = resourceVariablesPart.getOrBuild {
sourcePsi.resourceList
?.filterIsInstance<PsiResourceVariable>()
?.map { JavaUVariable.create(it, this) }
?: emptyList()
sourcePsi.resourceList?.mapNotNull { resourceListElem ->
when (resourceListElem) {
is PsiResourceVariable -> JavaUVariable.create(resourceListElem, this)
is PsiResourceExpression -> JavaConverter.convertOrEmpty(resourceListElem.expression, this)
else -> null
}
} ?: emptyList()
}
override val hasResources: Boolean

View File

@@ -13,3 +13,9 @@ foo -> UMethod (name = foo) from PsiIdentifier:foo
path -> USimpleNameReferenceExpression (identifier = path) from PsiIdentifier:path
br -> USimpleNameReferenceExpression (identifier = br) from PsiIdentifier:br
readLine -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from PsiIdentifier:readLine
foo -> UMethod (name = foo) from PsiIdentifier:foo
BufferedReader -> USimpleNameReferenceExpression (identifier = BufferedReader) from PsiIdentifier:BufferedReader
br -> UParameter (name = br) from PsiIdentifier:br
br -> USimpleNameReferenceExpression (identifier = br) from PsiIdentifier:br
br -> USimpleNameReferenceExpression (identifier = br) from PsiIdentifier:br
readLine -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from PsiIdentifier:readLine

View File

@@ -18,9 +18,14 @@ import java.io.FileReader;
public class TryWithResources {
public void foo() {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
public void foo(BufferedReader br) {
try (br) {
return br.readLine();
}
}
}

View File

@@ -17,3 +17,14 @@ UFile (package = )
USimpleNameReferenceExpression (identifier = br)
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
UIdentifier (Identifier (readLine))
UMethod (name = foo)
UParameter (name = br)
UBlockExpression
UTryExpression (with resources)
USimpleNameReferenceExpression (identifier = br)
UBlockExpression
UReturnExpression
UQualifiedReferenceExpression
USimpleNameReferenceExpression (identifier = br)
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
UIdentifier (Identifier (readLine))

View File

@@ -11,3 +11,8 @@ java -> USimpleNameReferenceExpression (identifier = java) from PsiJavaCodeRefer
readLine -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from PsiMethodCallExpression:br.readLine()
readLine -> UQualifiedReferenceExpression from PsiReferenceExpression:br.readLine
br -> USimpleNameReferenceExpression (identifier = br) from PsiReferenceExpression:br
BufferedReader -> USimpleNameReferenceExpression (identifier = BufferedReader) from PsiJavaCodeReferenceElement:BufferedReader
br -> USimpleNameReferenceExpression (identifier = br) from PsiReferenceExpression:br
readLine -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from PsiMethodCallExpression:br.readLine()
readLine -> UQualifiedReferenceExpression from PsiReferenceExpression:br.readLine
br -> USimpleNameReferenceExpression (identifier = br) from PsiReferenceExpression:br

View File

@@ -8,4 +8,10 @@ public class TryWithResources {
}
}
public fun foo(br: java.io.BufferedReader) : void {
try (br){
return br.readLine()
}
}
}

View File

@@ -13,3 +13,8 @@ UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = ja
UReturnExpression -> UQualifiedReferenceExpression -> PsiMethod:readLine: readLine
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) -> UQualifiedReferenceExpression -> PsiMethod:readLine: readLine
UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = br) -> PsiResourceVariable:br: br
UTypeReferenceExpression (name = java.io.BufferedReader) -> USimpleNameReferenceExpression (identifier = BufferedReader) -> PsiClass:BufferedReader: BufferedReader
UTryExpression (with resources) -> USimpleNameReferenceExpression (identifier = br) -> PsiParameter:br: br
UReturnExpression -> UQualifiedReferenceExpression -> PsiMethod:readLine: readLine
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) -> UQualifiedReferenceExpression -> PsiMethod:readLine: readLine
UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = br) -> PsiParameter:br: br