mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[uast] small part of implementation of code generation/modification on UAST. reviewed in IDEA-CR-50669
GitOrigin-RevId: 89328f198c55576137f831c1963bf359cdae9fa9
This commit is contained in:
committed by
intellij-monorepo-bot
parent
63597e52a1
commit
fb0bfeda5a
@@ -51,6 +51,8 @@
|
||||
<extensionPoint qualifiedName="org.jetbrains.uast.uastLanguagePlugin" interface="org.jetbrains.uast.UastLanguagePlugin"/>
|
||||
<extensionPoint qualifiedName="org.jetbrains.uast.analysis.uastAnalysisPlugin"
|
||||
interface="org.jetbrains.uast.analysis.UastAnalysisPlugin"/>
|
||||
<extensionPoint qualifiedName="org.jetbrains.uast.generate.uastCodeGenerationPlugin"
|
||||
interface="org.jetbrains.uast.generate.UastCodeGenerationPlugin"/>
|
||||
<extensionPoint qualifiedName="com.intellij.jvm.declarationSearcher" beanClass="com.intellij.lang.LanguageExtensionPoint">
|
||||
<with attribute="implementationClass" implements="com.intellij.lang.jvm.source.JvmDeclarationSearcher"/>
|
||||
</extensionPoint>
|
||||
@@ -126,10 +128,8 @@
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.uast">
|
||||
<uastLanguagePlugin implementation="org.jetbrains.uast.java.JavaUastLanguagePlugin"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.uast.analysis">
|
||||
<uastAnalysisPlugin implementation="org.jetbrains.uast.java.analysis.JavaUastAnalysisPlugin"/>
|
||||
<analysis.uastAnalysisPlugin implementation="org.jetbrains.uast.java.analysis.JavaUastAnalysisPlugin"/>
|
||||
<generate.uastCodeGenerationPlugin implementation="org.jetbrains.uast.java.generate.JavaUastCodeGenerationPlugin"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij.jvm">
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.uast.generate
|
||||
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.openapi.extensions.ExtensionPointName
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiType
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.uast.*
|
||||
|
||||
@ApiStatus.Experimental
|
||||
interface UastCodeGenerationPlugin {
|
||||
companion object {
|
||||
val extensionPointName = ExtensionPointName<UastCodeGenerationPlugin>("org.jetbrains.uast.generate.uastCodeGenerationPlugin")
|
||||
private val extensions by lazy { extensionPointName.extensionList }
|
||||
|
||||
@JvmStatic
|
||||
fun byLanguage(language: Language) = extensions.firstOrNull { it.language == language }
|
||||
}
|
||||
|
||||
val language: Language
|
||||
|
||||
fun createBinaryExpression(leftOperand: UExpression, rightOperand: UExpression, operator: UastBinaryOperator): UBinaryExpression?
|
||||
|
||||
/**
|
||||
* Create binary expression, and possibly remove unnecessary parenthesis, so it could become [UPolyadicExpression], e.g
|
||||
* [createFlatBinaryExpression](1 + 2, 2, +) could produce 1 + 2 + 2, which is polyadic expression
|
||||
*/
|
||||
@JvmDefault
|
||||
fun createFlatBinaryExpression(leftOperand: UExpression, rightOperand: UExpression, operator: UastBinaryOperator): UPolyadicExpression? =
|
||||
createBinaryExpression(leftOperand, rightOperand, operator)
|
||||
|
||||
fun createSimpleReference(name: String, project: Project): USimpleNameReferenceExpression?
|
||||
|
||||
fun createSimpleReference(variable: UVariable): USimpleNameReferenceExpression?
|
||||
|
||||
fun createParenthesizedExpression(expression: UExpression): UParenthesizedExpression?
|
||||
|
||||
fun createReturnExpresion(expression: UExpression, inLambda: Boolean = false): UReturnExpression?
|
||||
|
||||
fun createLocalVariable(name: String?, type: PsiType?, initializer: UExpression, immutable: Boolean = false): ULocalVariable?
|
||||
|
||||
fun createBlockExpression(expressions: List<UExpression>, project: Project): UBlockExpression?
|
||||
|
||||
fun createLambdaExpression(parameters: List<UParameter>, body: UExpression): ULambdaExpression?
|
||||
|
||||
fun createDeclarationExpression(declarations: List<UDeclaration>, project: Project): UDeclarationsExpression?
|
||||
|
||||
fun <T: UElement> replace(oldElement: UElement, newElement: T, elementType: Class<T>): T?
|
||||
}
|
||||
|
||||
@ApiStatus.Experimental
|
||||
inline fun <reified T: UElement> UElement.replace(newElement: T): T? =
|
||||
this.getLanguagePlugin()
|
||||
.let { UastCodeGenerationPlugin.byLanguage(it.language) }
|
||||
?.replace(this, newElement, T::class.java)
|
||||
|
||||
@ApiStatus.Experimental
|
||||
inline fun <reified T : UElement> T.refreshed() = sourcePsi?.toUElementOfType<T>()
|
||||
|
||||
val UElement.generationPlugin: UastCodeGenerationPlugin?
|
||||
@ApiStatus.Experimental
|
||||
get() = getLanguagePlugin().let { UastCodeGenerationPlugin.byLanguage(it.language) }
|
||||
@@ -0,0 +1,200 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.uast.java.generate
|
||||
|
||||
import com.intellij.codeInsight.BlockUtils
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.lang.java.JavaLanguage
|
||||
import com.intellij.lang.jvm.JvmModifier
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager
|
||||
import com.intellij.psi.codeStyle.VariableKind
|
||||
import com.intellij.psi.impl.source.tree.CompositeElement
|
||||
import com.intellij.psi.util.PsiUtil
|
||||
import com.siyeh.ig.psiutils.ParenthesesUtils
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.generate.UastCodeGenerationPlugin
|
||||
import org.jetbrains.uast.java.*
|
||||
import java.lang.AssertionError
|
||||
|
||||
class JavaUastCodeGenerationPlugin : UastCodeGenerationPlugin {
|
||||
override fun <T: UElement> replace(oldElement: UElement, newElement: T, elementType: Class<T>): T? =
|
||||
newElement.sourcePsi?.let { oldElement.sourcePsi?.replace(it) }?.toUElementOfExpectedTypes(elementType)
|
||||
|
||||
override fun createDeclarationExpression(declarations: List<UDeclaration>, project: Project): UDeclarationsExpression? {
|
||||
return JavaUDeclarationsExpression(null, declarations)
|
||||
}
|
||||
|
||||
private fun PsiElementFactory.createExpresionStatement(expression: PsiExpression): PsiStatement? {
|
||||
val statement = createStatementFromText("x;", null) as? PsiExpressionStatement ?: return null
|
||||
statement.expression.replace(expression)
|
||||
return statement
|
||||
}
|
||||
|
||||
override fun createReturnExpresion(expression: UExpression, inLambda: Boolean): UReturnExpression? {
|
||||
val factory = JavaPsiFacade.getElementFactory(expression.sourcePsi?.project ?: return null)
|
||||
val returnStatement = factory.createStatementFromText("return ;", null) as? PsiReturnStatement ?: return null
|
||||
|
||||
(returnStatement as CompositeElement).addChild(expression.sourcePsi!!.node, returnStatement.lastChild.node)
|
||||
|
||||
return JavaUReturnExpression(returnStatement, null)
|
||||
}
|
||||
|
||||
override fun createLocalVariable(name: String?, type: PsiType?, initializer: UExpression, immutable: Boolean): ULocalVariable? {
|
||||
val initializerPsi = initializer.sourcePsi as? PsiExpression ?: return null
|
||||
|
||||
if (name == null) {
|
||||
return createLocalVariableWithSuggestedName(type, initializer, immutable)
|
||||
}
|
||||
|
||||
val factory = JavaPsiFacade.getElementFactory(initializerPsi.project)
|
||||
val variable = (type ?: initializer.getExpressionType())?.let { variableType ->
|
||||
factory.createVariableDeclarationStatement(name, variableType, initializerPsi,
|
||||
initializerPsi.context).declaredElements.firstOrNull() as? PsiLocalVariable
|
||||
} ?: return null
|
||||
|
||||
if (immutable && !variable.hasModifier(JvmModifier.FINAL)) {
|
||||
PsiUtil.setModifierProperty(variable, PsiModifier.FINAL, true)
|
||||
}
|
||||
|
||||
if (!immutable && variable.hasModifier(JvmModifier.FINAL)) {
|
||||
PsiUtil.setModifierProperty(variable, PsiModifier.FINAL, false)
|
||||
}
|
||||
|
||||
return JavaULocalVariable(variable, null)
|
||||
}
|
||||
|
||||
private fun createLocalVariableWithSuggestedName(type: PsiType?, initializer: UExpression, immutable: Boolean): ULocalVariable? {
|
||||
val initializerPsi = initializer.sourcePsi as? PsiExpression ?: return null
|
||||
val codeStyleManager = JavaCodeStyleManager.getInstance(initializerPsi.project)
|
||||
val resultType = type ?: initializerPsi.type ?: return null
|
||||
var suggestedNameInfo = codeStyleManager.suggestVariableName(VariableKind.LOCAL_VARIABLE, null, initializerPsi, resultType)
|
||||
suggestedNameInfo = codeStyleManager.suggestUniqueVariableName(suggestedNameInfo, initializerPsi, true)
|
||||
val name = suggestedNameInfo.names.firstOrNull() ?: return null
|
||||
return createLocalVariable(name, type, initializer, immutable)
|
||||
}
|
||||
|
||||
override fun createBlockExpression(expressions: List<UExpression>, project: Project): UBlockExpression? {
|
||||
val factory = JavaPsiFacade.getElementFactory(project)
|
||||
val blockStatement = BlockUtils.createBlockStatement(project)
|
||||
|
||||
for (expression in expressions) {
|
||||
if (expression is JavaUDeclarationsExpression) {
|
||||
for (declaration in expression.declarations) {
|
||||
if (declaration.sourcePsi is PsiLocalVariable) {
|
||||
blockStatement.codeBlock.add(declaration.sourcePsi?.parent as? PsiDeclarationStatement ?: return null)
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
expression.sourcePsi?.let { psi ->
|
||||
psi as? PsiStatement ?: (psi as? PsiExpression)?.let { factory.createExpresionStatement(it) }
|
||||
}?.let { blockStatement.codeBlock.add(it) } ?: return null
|
||||
}
|
||||
|
||||
return JavaUBlockExpression(blockStatement, null)
|
||||
}
|
||||
|
||||
override fun createLambdaExpression(parameters: List<UParameter>, body: UExpression): ULambdaExpression? {
|
||||
val factory = JavaPsiFacade.getElementFactory(body.sourcePsi?.project ?: return null)
|
||||
val lambda = factory.createExpressionFromText(
|
||||
buildString {
|
||||
parameters.joinTo(this, separator = ",", prefix = "(", postfix = ")") { "x" }
|
||||
|
||||
append("->")
|
||||
append("{}")
|
||||
},
|
||||
null
|
||||
) as? PsiLambdaExpression ?: return null
|
||||
|
||||
lambda.parameterList.parameters.forEachIndexed { i, p ->
|
||||
p.replace(parameters[i].sourcePsi ?: return null)
|
||||
}
|
||||
|
||||
if (lambda.parameterList.parameters.any { it.typeElement == null })
|
||||
lambda.parameterList.parameters.forEach {
|
||||
it.typeElement?.delete()
|
||||
if (it.children.getOrNull(1) !is PsiIdentifier)
|
||||
it.children.getOrNull(1)?.delete()
|
||||
}
|
||||
|
||||
if (lambda.parameterList.parametersCount == 1 && lambda.parameterList.parameters[0].typeElement == null) {
|
||||
lambda.parameterList.firstChild.delete()
|
||||
lambda.parameterList.lastChild.delete()
|
||||
}
|
||||
|
||||
val normalizedBody = when (val bodyPsi = body.sourcePsi) {
|
||||
is PsiExpression -> bodyPsi
|
||||
is PsiCodeBlock -> normalizeBlockForLambda(bodyPsi)
|
||||
is PsiBlockStatement -> normalizeBlockForLambda(bodyPsi.codeBlock)
|
||||
else -> return null
|
||||
}
|
||||
|
||||
lambda.body?.replace(normalizedBody) ?: return null
|
||||
|
||||
return JavaULambdaExpression(lambda, null)
|
||||
}
|
||||
|
||||
private fun normalizeBlockForLambda(block: PsiCodeBlock): PsiElement = block
|
||||
.takeIf { block.statementCount == 1 }
|
||||
?.let { block.statements[0] as? PsiReturnStatement }
|
||||
?.let { it.returnValue } ?: block
|
||||
|
||||
override fun createParenthesizedExpression(expression: UExpression): UParenthesizedExpression? {
|
||||
val factory = JavaPsiFacade.getElementFactory(expression.sourcePsi?.project ?: return null)
|
||||
val parenthesizedExpression = factory.createExpressionFromText("()", null) as? PsiParenthesizedExpression ?: return null
|
||||
parenthesizedExpression.children.getOrNull(1)?.replace(expression.sourcePsi ?: return null) ?: return null
|
||||
return JavaUParenthesizedExpression(parenthesizedExpression, null)
|
||||
}
|
||||
|
||||
override fun createSimpleReference(name: String, project: Project): USimpleNameReferenceExpression? {
|
||||
val factory = JavaPsiFacade.getElementFactory(project)
|
||||
val reference = factory.createExpressionFromText(name, null)
|
||||
return JavaUSimpleNameReferenceExpression(reference, name, null)
|
||||
}
|
||||
|
||||
override fun createSimpleReference(variable: UVariable): USimpleNameReferenceExpression? {
|
||||
return createSimpleReference(variable.name ?: return null, variable.sourcePsi?.project ?: return null)
|
||||
}
|
||||
|
||||
override val language: Language
|
||||
get() = JavaLanguage.INSTANCE
|
||||
|
||||
|
||||
override fun createBinaryExpression(leftOperand: UExpression,
|
||||
rightOperand: UExpression,
|
||||
operator: UastBinaryOperator): UBinaryExpression? {
|
||||
val project = leftOperand.sourcePsi?.project ?: return null
|
||||
val leftPsi = leftOperand.sourcePsi ?: return null
|
||||
val rightPsi = rightOperand.sourcePsi ?: return null
|
||||
val factory = JavaPsiFacade.getElementFactory(project)
|
||||
|
||||
val operatorSymbol = when (operator) {
|
||||
UastBinaryOperator.LOGICAL_AND -> "&&"
|
||||
else -> return null
|
||||
}
|
||||
val psiBinaryExpression = factory.createExpressionFromText("a $operatorSymbol b", null) as? PsiBinaryExpression
|
||||
?: return null
|
||||
psiBinaryExpression.lOperand.replace(leftPsi)
|
||||
psiBinaryExpression.rOperand?.replace(rightPsi)
|
||||
|
||||
return JavaUBinaryExpression(psiBinaryExpression, null)
|
||||
}
|
||||
|
||||
override fun createFlatBinaryExpression(leftOperand: UExpression,
|
||||
rightOperand: UExpression,
|
||||
operator: UastBinaryOperator): UPolyadicExpression? {
|
||||
val binaryExpression = createBinaryExpression(leftOperand, rightOperand, operator) ?: return null
|
||||
val binarySourcePsi = binaryExpression.sourcePsi as? PsiBinaryExpression ?: return null
|
||||
val factory = JavaPsiFacade.getElementFactory(binarySourcePsi.project)
|
||||
val dummyParent = factory.createStatementFromText("a;", null)
|
||||
dummyParent.firstChild.replace(binarySourcePsi)
|
||||
ParenthesesUtils.removeParentheses(dummyParent.firstChild as PsiExpression, false)
|
||||
return when(val result = dummyParent.firstChild) {
|
||||
is PsiBinaryExpression -> JavaUBinaryExpression(result, null)
|
||||
is PsiPolyadicExpression -> JavaUPolyadicExpression(result, null)
|
||||
else -> throw AssertionError("Unexpected type " + result.javaClass)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.uast.test.java
|
||||
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
|
||||
import junit.framework.TestCase
|
||||
|
||||
abstract class AbstractJavaUastLightTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
protected fun fail(message: String): Nothing {
|
||||
throw AssertionError(message)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.uast.test.java.generate
|
||||
|
||||
import com.intellij.lang.java.JavaLanguage
|
||||
import com.intellij.psi.*
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.generate.UastCodeGenerationPlugin
|
||||
import org.jetbrains.uast.generate.refreshed
|
||||
import org.jetbrains.uast.generate.replace
|
||||
import org.jetbrains.uast.test.java.AbstractJavaUastLightTest
|
||||
|
||||
class JavaUastGenerationTest : AbstractJavaUastLightTest() {
|
||||
|
||||
private val psiFactory: PsiElementFactory
|
||||
get() = JavaPsiFacade.getElementFactory(myFixture.project)
|
||||
private val generatePlugin: UastCodeGenerationPlugin
|
||||
get() = UastCodeGenerationPlugin.byLanguage(JavaLanguage.INSTANCE)!!
|
||||
|
||||
fun `test logical and operation with simple operands`() {
|
||||
val left = psiFactory.createExpressionFromText("true", null).toUElementOfType<UExpression>()
|
||||
?: fail("Cannot create left UExpression")
|
||||
val right = psiFactory.createExpressionFromText("false", null).toUElementOfType<UExpression>()
|
||||
?: fail("Cannot create right UExpression")
|
||||
|
||||
val expression = generatePlugin.createBinaryExpression(left, right, UastBinaryOperator.LOGICAL_AND)
|
||||
?: fail("Cannot create expression")
|
||||
|
||||
TestCase.assertEquals("true && false", expression.sourcePsi?.text)
|
||||
}
|
||||
|
||||
fun `test logical and operation with simple operands with parenthesis`() {
|
||||
val left = psiFactory.createExpressionFromText("(true)", null).toUElementOfType<UExpression>()
|
||||
?: fail("Cannot create left UExpression")
|
||||
val right = psiFactory.createExpressionFromText("(false)", null).toUElementOfType<UExpression>()
|
||||
?: fail("Cannot create right UExpression")
|
||||
|
||||
val expression = generatePlugin.createFlatBinaryExpression(left, right, UastBinaryOperator.LOGICAL_AND)
|
||||
?: fail("Cannot create expression")
|
||||
|
||||
TestCase.assertTrue(expression.sourcePsi is PsiBinaryExpression)
|
||||
TestCase.assertEquals("true && false", expression.sourcePsi?.text)
|
||||
}
|
||||
|
||||
fun `test logical and operation with simple operands with parenthesis polyadic`() {
|
||||
val left = psiFactory.createExpressionFromText("(true && false)", null).toUElementOfType<UExpression>()
|
||||
?: fail("Cannot create left UExpression")
|
||||
val right = psiFactory.createExpressionFromText("(false)", null).toUElementOfType<UExpression>()
|
||||
?: fail("Cannot create right UExpression")
|
||||
|
||||
val expression = generatePlugin.createFlatBinaryExpression(left, right, UastBinaryOperator.LOGICAL_AND)
|
||||
?: fail("Cannot create expression")
|
||||
|
||||
TestCase.assertTrue(expression.sourcePsi is PsiPolyadicExpression)
|
||||
TestCase.assertEquals("true && false && false", expression.sourcePsi?.text)
|
||||
}
|
||||
|
||||
fun `test simple reference creating from variable`() {
|
||||
val variable = psiFactory.createVariableDeclarationStatement(
|
||||
"a",
|
||||
PsiType.INT
|
||||
, null
|
||||
).declaredElements.getOrNull(0)?.toUElementOfType<UVariable>() ?: fail("cannot create variable")
|
||||
|
||||
val reference = generatePlugin.createSimpleReference(variable) ?: fail("cannot create reference")
|
||||
TestCase.assertEquals("a", reference.identifier)
|
||||
}
|
||||
|
||||
fun `test simple reference by name`() {
|
||||
val reference = generatePlugin.createSimpleReference("a", myFixture.project) ?: fail("cannot create reference")
|
||||
TestCase.assertEquals("a", reference.identifier)
|
||||
}
|
||||
|
||||
fun `test parenthesised expression`() {
|
||||
val expression = psiFactory.createExpressionFromText("a + b", null).toUElementOfType<UExpression>()
|
||||
?: fail("cannot create expression")
|
||||
val parenthesizedExpression = generatePlugin.createParenthesizedExpression(expression)
|
||||
?: fail("cannot create parenthesized expression")
|
||||
|
||||
TestCase.assertEquals("(a + b)", parenthesizedExpression.sourcePsi?.text)
|
||||
}
|
||||
|
||||
fun `test return expression`() {
|
||||
val expression = psiFactory.createExpressionFromText("a + b", null).toUElementOfType<UExpression>()
|
||||
?: fail("Cannot find plugin")
|
||||
|
||||
val returnExpression = generatePlugin.createReturnExpresion(expression) ?: fail("cannot create return expression")
|
||||
|
||||
TestCase.assertEquals("return a + b;", returnExpression.sourcePsi?.text)
|
||||
}
|
||||
|
||||
fun `test variable declaration without type`() {
|
||||
val expression = psiFactory.createExpressionFromText("1 + 2", null).toUElementOfType<UExpression>()
|
||||
?: fail("cannot create variable declaration")
|
||||
|
||||
val declaration = generatePlugin.createLocalVariable("a", null, expression) ?: fail("cannot create variable")
|
||||
|
||||
TestCase.assertEquals("int a = 1 + 2;", declaration.sourcePsi?.text)
|
||||
}
|
||||
|
||||
fun `test variable declaration with type`() {
|
||||
val expression = psiFactory.createExpressionFromText("b", null).toUElementOfType<UExpression>()
|
||||
?: fail("cannot create variable declaration")
|
||||
|
||||
val declaration = generatePlugin.createLocalVariable("a", PsiType.DOUBLE, expression) ?: fail("cannot create variable")
|
||||
|
||||
TestCase.assertEquals("double a = b;", declaration.sourcePsi?.text)
|
||||
}
|
||||
|
||||
fun `test final variable declaration`() {
|
||||
val expression = psiFactory.createExpressionFromText("b", null).toUElementOfType<UExpression>()
|
||||
?: fail("cannot create variable declaration")
|
||||
|
||||
val declaration = generatePlugin.createLocalVariable("a", PsiType.DOUBLE, expression, true) ?: fail("cannot create variable")
|
||||
|
||||
TestCase.assertEquals("final double a = b;", declaration.sourcePsi?.text)
|
||||
}
|
||||
|
||||
fun `test block expression`() {
|
||||
val statement1 = psiFactory.createStatementFromText("System.out.println();", null).toUElementOfType<UExpression>()
|
||||
?: fail("cannot create statement")
|
||||
val statement2 = psiFactory.createStatementFromText("System.out.println(2);", null).toUElementOfType<UExpression>()
|
||||
?: fail("cannot create statement")
|
||||
|
||||
val block = generatePlugin.createBlockExpression(listOf(statement1, statement2), myFixture.project) ?: fail("cannot create block")
|
||||
|
||||
TestCase.assertEquals("{" +
|
||||
"System.out.println();" +
|
||||
"System.out.println(2);" +
|
||||
"}", block.sourcePsi?.text)
|
||||
}
|
||||
|
||||
fun `test lambda expression`() {
|
||||
val statement = psiFactory.createStatementFromText("System.out.println();", null).toUElementOfType<UExpression>()
|
||||
?: fail("cannot create statement")
|
||||
|
||||
val parameter1 = psiFactory.createParameter("a", PsiType.INT).toUElementOfType<UParameter>() ?: fail("cannot create parameter")
|
||||
|
||||
val parameter2 = psiFactory.createParameter("b", PsiType.INT).toUElementOfType<UParameter>() ?: fail("cannot create parameter")
|
||||
(parameter2.sourcePsi as PsiParameter).typeElement?.delete()
|
||||
(parameter2.sourcePsi as PsiParameter).children[1].delete()
|
||||
|
||||
val lambda = generatePlugin.createLambdaExpression(listOf(parameter1, parameter2), statement) ?: fail("cannot create lambda")
|
||||
|
||||
TestCase.assertEquals("(a,b)->System.out.println()", lambda.sourcePsi?.text)
|
||||
}
|
||||
|
||||
fun `test lambda expression with simplified block body`() {
|
||||
val block = psiFactory.createStatementFromText("{ return \"10\"; }", null).toUElementOfType<UBlockExpression>()
|
||||
?: fail("cannot create block")
|
||||
|
||||
val parameter1 = psiFactory.createParameter("a", PsiType.INT).toUElementOfType<UParameter>() ?: fail("cannot create parameter")
|
||||
(parameter1.sourcePsi as PsiParameter).typeElement?.delete()
|
||||
(parameter1.sourcePsi as PsiParameter).children[1].delete()
|
||||
val lambda = generatePlugin.createLambdaExpression(listOf(parameter1), block) ?: fail("cannot create lambda")
|
||||
TestCase.assertEquals("""a->"10"""", lambda.sourcePsi?.text)
|
||||
}
|
||||
|
||||
fun `test function argument replacement`() {
|
||||
val expression = psiFactory.createExpressionFromText("f(a)", null).toUElementOfType<UCallExpression>()
|
||||
?: fail("cannot create expression")
|
||||
val newArgument = psiFactory.createExpressionFromText("b", null).toUElementOfType<USimpleNameReferenceExpression>()
|
||||
?: fail("cannot create reference")
|
||||
|
||||
TestCase.assertNotNull(expression.valueArguments[0].replace(newArgument))
|
||||
val updated = expression.refreshed() ?: fail("cannot update expression")
|
||||
TestCase.assertEquals("f", updated.methodName)
|
||||
TestCase.assertTrue(updated.valueArguments[0] is USimpleNameReferenceExpression)
|
||||
TestCase.assertEquals("b", (updated.valueArguments[0] as USimpleNameReferenceExpression).identifier)
|
||||
}
|
||||
|
||||
fun `test suggested name`() {
|
||||
val expression = psiFactory.createExpressionFromText("f(a) + 1", null).toUElementOfType<UExpression>()
|
||||
?: fail("cannot create expression")
|
||||
val variable = generatePlugin.createLocalVariable(null, PsiType.INT, expression, true)
|
||||
?: fail("cannot create variable")
|
||||
|
||||
TestCase.assertEquals("final int i = f(a) + 1;", variable.sourcePsi?.text)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user