Surround with try/catch should generate more Kotlin-style code (KT-5435)

#KT-5435 Fixed
This commit is contained in:
shiraji
2016-10-09 12:10:45 +03:00
committed by Nikolay Krasko
parent c7c51a3d6b
commit 06dad5f45b
19 changed files with 97 additions and 57 deletions
@@ -50,17 +50,22 @@ fun move(container: PsiElement, statements: Array<PsiElement>, generateDefaultIn
val scope = LocalSearchScope(container)
val lastStatementOffset = statements[statements.size - 1].textRange.endOffset
for (statement in statements) {
statements.forEachIndexed { i, statement ->
if (needToDeclareOut(statement, lastStatementOffset, scope)) {
val property = statement as? KtProperty
if (property?.initializer != null) {
var declaration = createVariableDeclaration(property, generateDefaultInitializers)
declaration = container.addBefore(declaration, dummyFirstStatement) as KtProperty
propertiesDeclarations.add(declaration)
container.addAfter(psiFactory.createNewLine(), declaration)
val assignment = createVariableAssignment(property)
resultStatements.add(property.replace(assignment))
if (i == statements.size - 1) {
kotlinStyleDeclareOut(container, dummyFirstStatement, resultStatements, propertiesDeclarations, property)
} else {
declareOut(
container,
dummyFirstStatement,
generateDefaultInitializers,
resultStatements,
propertiesDeclarations,
property
)
}
} else {
val newStatement = container.addBefore(statement, dummyFirstStatement)
container.addAfter(psiFactory.createNewLine(), newStatement)
@@ -79,6 +84,38 @@ fun move(container: PsiElement, statements: Array<PsiElement>, generateDefaultIn
return PsiUtilCore.toPsiElementArray(resultStatements)
}
private fun kotlinStyleDeclareOut(
container: PsiElement,
dummyFirstStatement: PsiElement,
resultStatements: ArrayList<PsiElement>,
propertiesDeclarations: ArrayList<KtProperty>,
property: KtProperty
) {
val name = property.name ?: return
var declaration = KtPsiFactory(property).createProperty(name, property.typeReference?.text, property.isVar, null)
declaration = container.addBefore(declaration, dummyFirstStatement) as KtProperty
container.addAfter(KtPsiFactory(declaration).createEQ(), declaration)
propertiesDeclarations.add(declaration)
property.initializer?.let {
resultStatements.add(property.replace(it))
}
}
private fun declareOut(
container: PsiElement,
dummyFirstStatement: PsiElement,
generateDefaultInitializers: Boolean,
resultStatements: ArrayList<PsiElement>,
propertiesDeclarations: ArrayList<KtProperty>,
property: KtProperty
) {
var declaration = createVariableDeclaration(property, generateDefaultInitializers)
declaration = container.addBefore(declaration, dummyFirstStatement) as KtProperty
propertiesDeclarations.add(declaration)
val assignment = createVariableAssignment(property)
resultStatements.add(property.replace(assignment))
}
private fun createVariableAssignment(property: KtProperty): KtBinaryExpression {
val propertyName = property.name ?: error("Property should have a name " + property.text)
val assignment = KtPsiFactory(property).createExpression("$propertyName = x") as KtBinaryExpression
@@ -105,11 +142,10 @@ private fun getPropertyType(property: KtProperty): KotlinType {
private fun createProperty(property: KtProperty, propertyType: KotlinType, initializer: String?): KtProperty {
val typeRef = property.typeReference
var typeString: String? = null
if (typeRef != null) {
typeString = typeRef.text
} else if (!propertyType.isError) {
typeString = IdeDescriptorRenderers.SOURCE_CODE.renderType(propertyType)
val typeString = when {
typeRef != null -> typeRef.text
!propertyType.isError -> IdeDescriptorRenderers.SOURCE_CODE.renderType(propertyType)
else -> null
}
return KtPsiFactory(property).createProperty(property.name!!, typeString, property.isVar, initializer)
@@ -1,9 +1,8 @@
fun foo() {
val a: String
val b: String
<selection>run</selection> {
val b = <selection>run</selection> {
a = "aaa"
b = "aaa"
"aaa"
}
a.charAt(1)
@@ -3,9 +3,9 @@ fun foo() {
fun test() {}
}
val d: A
val d: A =
if (<caret>) {
d = A()
A()
}
d.test()
@@ -1,9 +1,8 @@
fun foo() {
val a: String
val b: String
if (<caret>) {
val b = if (<caret>) {
a = "aaa"
b = a
a
}
a.charAt(1)
@@ -1,7 +1,6 @@
fun foo() {
val a: kotlin.test.Asserter?
if (<caret>) {
a = null
val a: kotlin.test.Asserter? = if (<caret>) {
null
}
a?.charAt(1)
@@ -3,9 +3,8 @@ package test
class A {}
fun foo() {
val a: A
if (<caret>) {
a = test.A()
val a = if (<caret>) {
test.A()
}
a.hashCode()
@@ -1,7 +1,6 @@
fun foo() {
val a: String
if () {
a = "aaa"
val a: String = if () {
"aaa"
}
a.charAt(1)
@@ -1,7 +1,6 @@
fun foo() {
val a: String
if () {
a = "aaa"
val a = if () {
"aaa"
}
a.charAt(1)
@@ -1,7 +1,6 @@
fun foo() {
var a: Boolean = false
if (<caret>) {
a = true
var a: Boolean = if (<caret>) {
true
}
a = true
}
@@ -1,7 +1,6 @@
fun foo() {
var a: String? = null
if (<caret>) {
a = "aaa"
var a: String? = if (<caret>) {
"aaa"
}
a = "bbb"
}
@@ -5,15 +5,14 @@ fun foo() {
var d: Long = 0
var e: Short = 0
var f: Double = 0.0
var g: Float = 0.0f
if () {
var g: Float = if () {
a = 1
b = 1
c = 1
d = 1
e = 1
f = 1
g = 1
1
}
a = 2
b = 2
@@ -1,7 +1,6 @@
fun foo() {
var a: String = ""
if () {
a = "aaa"
var a: String = if () {
"aaa"
}
a.charAt(1)
@@ -1,7 +1,6 @@
fun foo() {
var a: String = ""
if () {
a = "aaa"
var a = if () {
"aaa"
}
a.charAt(1)
@@ -1,7 +1,6 @@
fun foo() {
val a: String?
if (<caret>) {
a = "aaa"
val a: String? = if (<caret>) {
"aaa"
} else {
}
a.toString()
@@ -1,7 +1,6 @@
fun foo() {
var a: String?
if (<caret>) {
a = "aaa"
var a: String? = if (<caret>) {
"aaa"
} else {
}
a = "bbb"
@@ -1,9 +1,8 @@
fun foo() {
val a: String
val b: String
try {
val b = try {
a = "aaa"
b = "aaa"
"aaa"
} catch (e: <selection>Exception</selection>) {
}
@@ -0,0 +1,5 @@
fun foo() {
<selection>val a = "aaa"</selection>
a.charAt(1)
}
@@ -0,0 +1,8 @@
fun foo() {
val a = try {
"aaa"
} catch (e: <selection><caret>Exception</selection>) {
}
a.charAt(1)
}
@@ -587,6 +587,11 @@ public class SurroundWithTestGenerated extends AbstractSurroundWithTest {
runTest("idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOut.kt");
}
@TestMetadata("moveDeclarationsOutSingleStatement.kt")
public void testMoveDeclarationsOutSingleStatement() throws Exception {
runTest("idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOutSingleStatement.kt");
}
@TestMetadata("multiExpression.kt")
public void testMultiExpression() throws Exception {
runTest("idea/testData/codeInsight/surroundWith/tryCatch/multiExpression.kt");