@@ -44,23 +44,26 @@ class ImplementAbstractMembersQuickFix : QuickFix {
4444
4545 // If the client side and the server side diagnostics contain a valid diagnostic for this range.
4646 if (diagnostic != null && anyDiagnosticMatch(kotlinDiagnostics, startCursor, endCursor)) {
47- // Get the class with the missing functions
47+ // Get the class with the missing members
4848 val kotlinClass = file.parseAtPoint(startCursor)
4949 if (kotlinClass is KtClass ) {
5050 // Get the functions that need to be implemented
51- val functionsToImplement = getAbstractFunctionStubs (file, kotlinClass)
51+ val membersToImplement = getAbstractMembersStubs (file, kotlinClass)
5252
5353 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
5555 val padding = getDeclarationPadding(file, kotlinClass)
56+
5657 // 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()
5861
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
6164 val newText = System .lineSeparator() + System .lineSeparator() + padding + it
62- TextEdit (Range (newFunctionStartPosition, newFunctionStartPosition ), newText)
63- }
65+ TextEdit (Range (newMembersStartPosition, newMembersStartPosition ), newText)
66+ } + bodyAppendEnd
6467
6568 val codeAction = CodeAction ()
6669 codeAction.edit = WorkspaceEdit (mapOf (uri to textEdits))
@@ -80,7 +83,7 @@ fun findDiagnosticMatch(diagnostics: List<Diagnostic>, range: Range) =
8083private fun anyDiagnosticMatch (diagnostics : Diagnostics , startCursor : Int , endCursor : Int ) =
8184 diagnostics.any { diagnosticMatch(it, startCursor, endCursor, hashSetOf(" ABSTRACT_MEMBER_NOT_IMPLEMENTED" , " ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED" )) }
8285
83- private fun getAbstractFunctionStubs (file : CompiledFile , kotlinClass : KtClass ) =
86+ private fun getAbstractMembersStubs (file : CompiledFile , kotlinClass : KtClass ) =
8487 // For each of the super types used by this class
8588 kotlinClass.superTypeListEntries.mapNotNull {
8689 // Find the definition of this super type
@@ -211,16 +214,21 @@ private fun getDeclarationPadding(file: CompiledFile, kotlinClass: KtClass): Str
211214 return " " .repeat(paddingSize)
212215}
213216
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
216219 if (kotlinClass.declarations.isNotEmpty()) {
217220 val lastFunctionEndOffset = kotlinClass.declarations.last().endOffset
218221 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
220223 val body = kotlinClass.body
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
0 commit comments