mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[uast-java] Support for converting Java 12 "enhanced" switch expressions (IDEA-202555)
This commit is contained in:
@@ -69,7 +69,7 @@ private fun JavaAbstractUElement.unwrapSwitch(uParent: UElement): UElement {
|
||||
is JavaUCodeBlockExpression -> {
|
||||
val codeBlockParent = uParent.uastParent
|
||||
if (codeBlockParent is JavaUSwitchEntryList) {
|
||||
if (branchHasElement(psi, codeBlockParent.psi) { it is PsiSwitchLabelStatement }) {
|
||||
if (branchHasElement(psi, codeBlockParent.psi) { it is PsiSwitchLabelStatementBase }) {
|
||||
return codeBlockParent
|
||||
}
|
||||
val psiElement = psi ?: return uParent
|
||||
@@ -81,8 +81,16 @@ private fun JavaAbstractUElement.unwrapSwitch(uParent: UElement): UElement {
|
||||
return uParent
|
||||
}
|
||||
|
||||
is JavaUSwitchEntry -> {
|
||||
val parentSourcePsi = uParent.sourcePsi
|
||||
if (parentSourcePsi is PsiSwitchLabeledRuleStatement && parentSourcePsi.body?.children?.contains(psi) == true)
|
||||
return uParent.body
|
||||
else
|
||||
return uParent
|
||||
}
|
||||
|
||||
is USwitchExpression -> {
|
||||
val parentPsi = uParent.psi as PsiSwitchStatement
|
||||
val parentPsi = uParent.psi as PsiSwitchBlock
|
||||
return if (this === uParent.body || branchHasElement(psi, parentPsi) { it === parentPsi.expression })
|
||||
uParent
|
||||
else
|
||||
|
||||
@@ -251,6 +251,7 @@ internal object JavaConverter {
|
||||
is PsiClassObjectAccessExpression -> expr<UClassLiteralExpression>(build(::JavaUClassLiteralExpression))
|
||||
is PsiArrayAccessExpression -> expr<UArrayAccessExpression>(build(::JavaUArrayAccessExpression))
|
||||
is PsiLambdaExpression -> expr<ULambdaExpression>(build(::JavaULambdaExpression))
|
||||
is PsiSwitchExpression -> expr<USwitchExpression>(build(::JavaUSwitchExpression))
|
||||
else -> expr<UExpression>(build(::UnknownJavaExpression))
|
||||
}
|
||||
}
|
||||
@@ -290,10 +291,10 @@ internal object JavaConverter {
|
||||
is PsiSynchronizedStatement -> expr<UBlockExpression>(build(::JavaUSynchronizedExpression))
|
||||
is PsiTryStatement -> expr<UTryExpression>(build(::JavaUTryExpression))
|
||||
is PsiEmptyStatement -> expr<UExpression> { UastEmptyExpression(el.parent?.toUElement()) }
|
||||
is PsiSwitchLabelStatement -> expr<UExpression> {
|
||||
is PsiSwitchLabelStatementBase -> expr<UExpression> {
|
||||
when {
|
||||
givenParent is JavaUSwitchEntryList -> givenParent.findUSwitchEntryForLabel(el)
|
||||
givenParent == null -> PsiTreeUtil.getParentOfType(el, PsiSwitchStatement::class.java)?.let {
|
||||
givenParent == null -> PsiTreeUtil.getParentOfType(el, PsiSwitchBlock::class.java)?.let {
|
||||
JavaUSwitchExpression(it, null).body.findUSwitchEntryForLabel(el)
|
||||
}
|
||||
else -> null
|
||||
|
||||
+14
-10
@@ -15,17 +15,14 @@
|
||||
*/
|
||||
package org.jetbrains.uast.java
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiStatement
|
||||
import com.intellij.psi.PsiSwitchLabelStatement
|
||||
import com.intellij.psi.PsiSwitchStatement
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.source.tree.ChildRole
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.java.expressions.JavaUExpressionList
|
||||
import org.jetbrains.uast.java.kinds.JavaSpecialExpressionKinds
|
||||
|
||||
class JavaUSwitchExpression(
|
||||
override val psi: PsiSwitchStatement,
|
||||
override val psi: PsiSwitchBlock,
|
||||
givenParent: UElement?
|
||||
) : JavaAbstractUExpression(givenParent), USwitchExpression {
|
||||
override val expression: UExpression by lz { JavaConverter.convertOrEmpty(psi.expression, this) }
|
||||
@@ -37,7 +34,7 @@ class JavaUSwitchExpression(
|
||||
|
||||
}
|
||||
|
||||
class JavaUSwitchEntryList(override val psi: PsiSwitchStatement, override val uastParent: JavaUSwitchExpression) :
|
||||
class JavaUSwitchEntryList(override val psi: PsiSwitchBlock, override val uastParent: JavaUSwitchExpression) :
|
||||
JavaAbstractUExpression(uastParent), UExpressionList {
|
||||
|
||||
override val kind: UastSpecialExpressionKind
|
||||
@@ -49,10 +46,13 @@ class JavaUSwitchEntryList(override val psi: PsiSwitchStatement, override val ua
|
||||
|
||||
private val switchEntries: Lazy<List<JavaUSwitchEntry>> = lazy {
|
||||
val statements = psi.body?.statements ?: return@lazy emptyList<JavaUSwitchEntry>()
|
||||
var currentLabels = listOf<PsiSwitchLabelStatement>()
|
||||
var currentLabels = listOf<PsiSwitchLabelStatementBase>()
|
||||
var currentBody = listOf<PsiStatement>()
|
||||
val result = mutableListOf<JavaUSwitchEntry>()
|
||||
for (statement in statements) {
|
||||
if (statement is PsiSwitchLabeledRuleStatement) {
|
||||
result += JavaUSwitchEntry(listOf(statement), listOfNotNull(statement.body), this)
|
||||
}
|
||||
if (statement is PsiSwitchLabelStatement) {
|
||||
if (currentBody.isEmpty()) {
|
||||
currentLabels += statement
|
||||
@@ -76,9 +76,13 @@ class JavaUSwitchEntryList(override val psi: PsiSwitchStatement, override val ua
|
||||
|
||||
override val expressions: List<JavaUSwitchEntry> get() = switchEntries.value
|
||||
|
||||
fun findUSwitchEntryForLabel(switchLabelStatement: PsiSwitchLabelStatement): JavaUSwitchEntry? {
|
||||
fun findUSwitchEntryForLabel(switchLabelStatement: PsiSwitchLabelStatementBase): JavaUSwitchEntry? {
|
||||
if (switchEntries.isInitialized()) return switchEntries.value.find { it.labels.contains(switchLabelStatement) }
|
||||
|
||||
if (switchLabelStatement is PsiSwitchLabeledRuleStatement) {
|
||||
return JavaUSwitchEntry(listOf(switchLabelStatement), listOfNotNull(switchLabelStatement.body), this)
|
||||
}
|
||||
|
||||
val bodyStart = switchLabelStatement.nextSiblings.find { it !is PsiSwitchLabelStatement } ?: return null
|
||||
val body = bodyStart.nextSiblings.takeWhile { it !is PsiSwitchLabelStatement }.filterIsInstance<PsiStatement>().toList()
|
||||
val labels = switchLabelStatement.prevSiblings.takeWhile { it is PsiSwitchLabelStatement }.filterIsInstance<PsiSwitchLabelStatement>().toList()
|
||||
@@ -103,11 +107,11 @@ private val PsiElement.prevSiblings: Sequence<PsiElement> get() = generateSequen
|
||||
|
||||
|
||||
class JavaUSwitchEntry(
|
||||
val labels: List<PsiSwitchLabelStatement>,
|
||||
val labels: List<PsiSwitchLabelStatementBase>,
|
||||
val statements: List<PsiStatement>,
|
||||
givenParent: UElement?
|
||||
) : JavaAbstractUExpression(givenParent), USwitchClauseExpressionWithBody {
|
||||
override val psi: PsiSwitchLabelStatement = labels.first()
|
||||
override val psi: PsiSwitchLabelStatementBase = labels.first()
|
||||
|
||||
override val caseValues: List<UExpression> by lz {
|
||||
labels.mapNotNull {
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
public class Main {
|
||||
|
||||
private static String getString() {
|
||||
var str = "abc";
|
||||
|
||||
final String numericString =
|
||||
switch (str) {
|
||||
case "foo" -> "FOO";
|
||||
case "bar" -> "BAR";
|
||||
case "baz" -> "bAz";
|
||||
default -> "default";
|
||||
};
|
||||
|
||||
final String numericString2 =
|
||||
switch (str) {
|
||||
case "foo":
|
||||
break "FOO";
|
||||
case "bar":
|
||||
break "BAR";
|
||||
case "baz":
|
||||
break "bAz";
|
||||
default:
|
||||
break "default";
|
||||
};
|
||||
return numericString + numericString2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
UFile (package = )
|
||||
UClass (name = Main)
|
||||
UMethod (name = getString)
|
||||
UBlockExpression
|
||||
UDeclarationsExpression
|
||||
ULocalVariable (name = str)
|
||||
ULiteralExpression (value = "abc")
|
||||
UDeclarationsExpression
|
||||
ULocalVariable (name = numericString)
|
||||
USwitchExpression
|
||||
USimpleNameReferenceExpression (identifier = str)
|
||||
UExpressionList (switch)
|
||||
USwitchClauseExpressionWithBody
|
||||
ULiteralExpression (value = "foo")
|
||||
UExpressionList (switch_entry)
|
||||
ULiteralExpression (value = "FOO")
|
||||
USwitchClauseExpressionWithBody
|
||||
ULiteralExpression (value = "bar")
|
||||
UExpressionList (switch_entry)
|
||||
ULiteralExpression (value = "BAR")
|
||||
USwitchClauseExpressionWithBody
|
||||
ULiteralExpression (value = "baz")
|
||||
UExpressionList (switch_entry)
|
||||
ULiteralExpression (value = "bAz")
|
||||
USwitchClauseExpressionWithBody
|
||||
UDefaultCaseExpression
|
||||
UExpressionList (switch_entry)
|
||||
ULiteralExpression (value = "default")
|
||||
UDeclarationsExpression
|
||||
ULocalVariable (name = numericString2)
|
||||
USwitchExpression
|
||||
USimpleNameReferenceExpression (identifier = str)
|
||||
UExpressionList (switch)
|
||||
USwitchClauseExpressionWithBody
|
||||
ULiteralExpression (value = "foo")
|
||||
UExpressionList (switch_entry)
|
||||
UBreakExpression (label = null)
|
||||
USwitchClauseExpressionWithBody
|
||||
ULiteralExpression (value = "bar")
|
||||
UExpressionList (switch_entry)
|
||||
UBreakExpression (label = null)
|
||||
USwitchClauseExpressionWithBody
|
||||
ULiteralExpression (value = "baz")
|
||||
UExpressionList (switch_entry)
|
||||
UBreakExpression (label = null)
|
||||
USwitchClauseExpressionWithBody
|
||||
UDefaultCaseExpression
|
||||
UExpressionList (switch_entry)
|
||||
UBreakExpression (label = null)
|
||||
UReturnExpression
|
||||
UBinaryExpression (operator = +)
|
||||
USimpleNameReferenceExpression (identifier = numericString)
|
||||
USimpleNameReferenceExpression (identifier = numericString2)
|
||||
@@ -0,0 +1,42 @@
|
||||
public class Main {
|
||||
private static fun getString() : java.lang.String {
|
||||
var str: var = "abc"
|
||||
final var numericString: java.lang.String = switch (str)
|
||||
"foo" -> {
|
||||
"FOO"
|
||||
}
|
||||
|
||||
"bar" -> {
|
||||
"BAR"
|
||||
}
|
||||
|
||||
"baz" -> {
|
||||
"bAz"
|
||||
}
|
||||
|
||||
else -> {
|
||||
"default"
|
||||
}
|
||||
|
||||
|
||||
final var numericString2: java.lang.String = switch (str)
|
||||
"foo" -> {
|
||||
break
|
||||
}
|
||||
|
||||
"bar" -> {
|
||||
break
|
||||
}
|
||||
|
||||
"baz" -> {
|
||||
break
|
||||
}
|
||||
|
||||
else -> {
|
||||
break
|
||||
}
|
||||
|
||||
|
||||
return numericString + numericString2
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,9 @@ class SimpleJavaRenderLogTest : AbstractJavaRenderLogTest() {
|
||||
@Test
|
||||
fun testEnumSwitch() = doTest("Simple/EnumSwitch.java")
|
||||
|
||||
@Test
|
||||
fun testEnhancedSwitch() = doTest("Simple/EnhancedSwitch.java")
|
||||
|
||||
@Test
|
||||
fun testLocalClass() = doTest("Simple/LocalClass.java")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user