Skip to content

Commit d8c7bab

Browse files
committed
Fix issue where nothing happens on empty body for implement abstract
members quick fix
1 parent 5df1a00 commit d8c7bab

File tree

3 files changed

+49
-3
lines changed

3 files changed

+49
-3
lines changed

server/src/main/kotlin/org/javacs/kt/codeaction/quickfix/ImplementAbstractMembersQuickFix.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,17 @@ class ImplementAbstractMembersQuickFix : QuickFix {
5353
val uri = file.parse.toPath().toUri().toString()
5454
// Get the padding to be introduced before the function declarations
5555
val padding = getDeclarationPadding(file, kotlinClass)
56+
5657
// Get the location where the new code will be placed
5758
val newFunctionStartPosition = getNewFunctionStartPosition(file, kotlinClass)
59+
val bodyAppendBeginning = listOf(TextEdit(Range(newFunctionStartPosition, newFunctionStartPosition), "{")).takeIf { kotlinClass.hasNoBody() } ?: emptyList()
60+
val bodyAppendEnd = listOf(TextEdit(Range(newFunctionStartPosition, newFunctionStartPosition), System.lineSeparator() + "}")).takeIf { kotlinClass.hasNoBody() } ?: emptyList()
5861

59-
val textEdits = functionsToImplement.map {
62+
val textEdits = bodyAppendBeginning + functionsToImplement.map {
6063
// We leave two new lines before the function is inserted
6164
val newText = System.lineSeparator() + System.lineSeparator() + padding + it
6265
TextEdit(Range(newFunctionStartPosition, newFunctionStartPosition), newText)
63-
}
66+
} + bodyAppendEnd
6467

6568
val codeAction = CodeAction()
6669
codeAction.edit = WorkspaceEdit(mapOf(uri to textEdits))
@@ -221,6 +224,11 @@ private fun getNewFunctionStartPosition(file: CompiledFile, kotlinClass: KtClass
221224
if (body != null) {
222225
position(file.content, body.startOffset + 1)
223226
} else {
224-
null
227+
// function has no body. We have to create one. New position is right after entire kotlin class text (with space)
228+
val newPosCorrectLine = position(file.content, kotlinClass.startOffset + 1)
229+
newPosCorrectLine.character = (kotlinClass.text.length + 2)
230+
newPosCorrectLine
225231
}
226232
}
233+
234+
private fun KtClass.hasNoBody() = null == this.body

server/src/test/kotlin/org/javacs/kt/QuickFixesTest.kt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,36 @@ class ImplementAbstractMembersQuickFixSameFileTest : SingleFileTestFixture("quic
241241
assertThat(memberToImplementEdit?.range, equalTo(range(38, 31, 38, 31)))
242242
assertThat(memberToImplementEdit?.newText, equalTo(System.lineSeparator() + System.lineSeparator() + " override fun myFun() { }"))
243243
}
244+
245+
@Test
246+
fun `should find abstract members when class has no body (square brackets)`() {
247+
val only = listOf(CodeActionKind.QuickFix)
248+
val codeActionParams = codeActionParams(file, 47, 1, 47, 12, diagnostics, only)
249+
250+
val codeActionResult = languageServer.textDocumentService.codeAction(codeActionParams).get()
251+
252+
assertThat(codeActionResult, hasSize(1))
253+
val codeAction = codeActionResult[0].right
254+
assertThat(codeAction.kind, equalTo(CodeActionKind.QuickFix))
255+
assertThat(codeAction.title, equalTo("Implement abstract members"))
256+
257+
val textEdit = codeAction.edit.changes
258+
val key = workspaceRoot.resolve(file).toUri().toString()
259+
assertThat(textEdit.containsKey(key), equalTo(true))
260+
assertThat(textEdit[key], hasSize(3))
261+
262+
val firstMemberToImplementEdit = textEdit[key]?.get(0)
263+
assertThat(firstMemberToImplementEdit?.range, equalTo(range(47, 23, 47, 23)))
264+
assertThat(firstMemberToImplementEdit?.newText, equalTo("{"))
265+
266+
val secondMemberToImplementEdit = textEdit[key]?.get(1)
267+
assertThat(secondMemberToImplementEdit?.range, equalTo(range(47, 23, 47, 23)))
268+
assertThat(secondMemberToImplementEdit?.newText, equalTo(System.lineSeparator() + System.lineSeparator() + " override fun behaviour() { }"))
269+
270+
val thirdMemberToImplementEdit = textEdit[key]?.get(2)
271+
assertThat(thirdMemberToImplementEdit?.range, equalTo(range(47, 23, 47, 23)))
272+
assertThat(thirdMemberToImplementEdit?.newText, equalTo(System.lineSeparator() + "}"))
273+
}
244274
}
245275

246276
class ImplementAbstractMembersQuickFixExternalLibraryTest : SingleFileTestFixture("quickfixes", "standardlib.kt") {

server/src/test/resources/quickfixes/samefile.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,11 @@ class MyImplClass : MyAbstract() {}
3737
class My2ndClass : MyAbstract() {
3838
override val name = "Nils"
3939
}
40+
41+
42+
// defect GH-366, part of the solution
43+
interface IThing {
44+
fun behaviour
45+
}
46+
47+
class Thing : IThing

0 commit comments

Comments
 (0)