@@ -44,23 +44,26 @@ class ImplementAbstractMembersQuickFix : QuickFix {
44
44
45
45
// If the client side and the server side diagnostics contain a valid diagnostic for this range.
46
46
if (diagnostic != null && anyDiagnosticMatch(kotlinDiagnostics, startCursor, endCursor)) {
47
- // Get the class with the missing functions
47
+ // Get the class with the missing members
48
48
val kotlinClass = file.parseAtPoint(startCursor)
49
49
if (kotlinClass is KtClass ) {
50
50
// Get the functions that need to be implemented
51
- val functionsToImplement = getAbstractFunctionStubs (file, kotlinClass)
51
+ val membersToImplement = getAbstractMembersStubs (file, kotlinClass)
52
52
53
53
val uri = file.parse.toPath().toUri().toString()
54
- // Get the padding to be introduced before the function declarations
54
+ // Get the padding to be introduced before the member declarations
55
55
val padding = getDeclarationPadding(file, kotlinClass)
56
+
56
57
// Get the location where the new code will be placed
57
- val newFunctionStartPosition = getNewFunctionStartPosition(file, kotlinClass)
58
+ val newMembersStartPosition = getNewMembersStartPosition(file, kotlinClass)
59
+ val bodyAppendBeginning = listOf (TextEdit (Range (newMembersStartPosition, newMembersStartPosition), " {" )).takeIf { kotlinClass.hasNoBody() } ? : emptyList()
60
+ val bodyAppendEnd = listOf (TextEdit (Range (newMembersStartPosition, newMembersStartPosition), System .lineSeparator() + " }" )).takeIf { kotlinClass.hasNoBody() } ? : emptyList()
58
61
59
- val textEdits = functionsToImplement .map {
60
- // We leave two new lines before the function is inserted
62
+ val textEdits = bodyAppendBeginning + membersToImplement .map {
63
+ // We leave two new lines before the member is inserted
61
64
val newText = System .lineSeparator() + System .lineSeparator() + padding + it
62
- TextEdit (Range (newFunctionStartPosition, newFunctionStartPosition ), newText)
63
- }
65
+ TextEdit (Range (newMembersStartPosition, newMembersStartPosition ), newText)
66
+ } + bodyAppendEnd
64
67
65
68
val codeAction = CodeAction ()
66
69
codeAction.edit = WorkspaceEdit (mapOf (uri to textEdits))
@@ -80,7 +83,7 @@ fun findDiagnosticMatch(diagnostics: List<Diagnostic>, range: Range) =
80
83
private fun anyDiagnosticMatch (diagnostics : Diagnostics , startCursor : Int , endCursor : Int ) =
81
84
diagnostics.any { diagnosticMatch(it, startCursor, endCursor, hashSetOf(" ABSTRACT_MEMBER_NOT_IMPLEMENTED" , " ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED" )) }
82
85
83
- private fun getAbstractFunctionStubs (file : CompiledFile , kotlinClass : KtClass ) =
86
+ private fun getAbstractMembersStubs (file : CompiledFile , kotlinClass : KtClass ) =
84
87
// For each of the super types used by this class
85
88
kotlinClass.superTypeListEntries.mapNotNull {
86
89
// Find the definition of this super type
@@ -211,16 +214,21 @@ private fun getDeclarationPadding(file: CompiledFile, kotlinClass: KtClass): Str
211
214
return " " .repeat(paddingSize)
212
215
}
213
216
214
- private fun getNewFunctionStartPosition (file : CompiledFile , kotlinClass : KtClass ): Position ? =
215
- // If the class is not empty, the new function will be put right after the last declaration
217
+ private fun getNewMembersStartPosition (file : CompiledFile , kotlinClass : KtClass ): Position ? =
218
+ // If the class is not empty, the new member will be put right after the last declaration
216
219
if (kotlinClass.declarations.isNotEmpty()) {
217
220
val lastFunctionEndOffset = kotlinClass.declarations.last().endOffset
218
221
position(file.content, lastFunctionEndOffset)
219
- } else { // Otherwise, the function is put at the beginning of the class
222
+ } else { // Otherwise, the member is put at the beginning of the class
220
223
val body = kotlinClass.body
221
224
if (body != null ) {
222
225
position(file.content, body.startOffset + 1 )
223
226
} 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
225
231
}
226
232
}
233
+
234
+ private fun KtClass.hasNoBody () = null == this .body
0 commit comments