Skip to content

Extract and refactor call formatter - #677

Open
AbdullinAM wants to merge 8 commits into
mainfrom
abdullin/call-formatter
Open

Extract and refactor call formatter#677
AbdullinAM wants to merge 8 commits into
mainfrom
abdullin/call-formatter

Conversation

@AbdullinAM

Copy link
Copy Markdown
Member
  • Extract call formatter into a separate interface
  • Introduce custom Indentation wrappers, mostly to simplify some code. GJF's indents have everything private, so we can't provide custom operator funs for them, requiring us to constantly keep a lot of indent instances
  • Extract everything related to GroupInfo into a separate file
  • Simplify some of the CallFormatter's existing implementations

Note: this PR is purely refactoring, none of the behaviours are changed. I'm planning to extract changes from #634 into a separate KotlikLangCallFormatter in the next PR

@AbdullinAM
AbdullinAM requested a review from qwwdfsad August 18, 2026 16:22
import org.jetbrains.kotlin.psi.psiUtil.startsWithComment
import org.jetbrains.ktfmt.format.ParseError

interface CallFormatter : KotlinAstFormatter {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for the future: please consider spelling explicitly in the commit whether the refactoring (e.g. extraction) is purely mechanical (same code, some names, same comments) or implies some additional non-trivial (e.g. not "moved it from visitX to formatX method") changes.

It will simplify the review process for housekeeping things a lot. Thanks!

Comment thread core/src/main/kotlin/org/jetbrains/ktfmt/format/visitor/GroupInfo.kt Outdated
import com.google.googlejavaformat.Indent
import com.google.googlejavaformat.Output

sealed class Indentation {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a KDoc: an example of what it is and what it represents (I understand it represents an indentation, but what exactly? In some units, as a forced break, or as something to operate on to properly make a GJF decision for block calls? Now to answer that I look into the usages)

import org.jetbrains.ktfmt.format.visitor.Indentation.Companion.ZERO
import org.jetbrains.ktfmt.format.visitor.Indentation.Companion.makeCond

interface CallFormatter : KotlinAstFormatter {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, a KDoc per our convention, please: what part of grammar it owns, what it formats, etc.

Comment thread core/src/main/kotlin/org/jetbrains/ktfmt/format/visitor/CallFormatter.kt Outdated
Comment thread core/src/main/kotlin/org/jetbrains/ktfmt/format/visitor/Indentation.kt Outdated
val blockComments =
bodyExpression.children().filter { it is PsiComment && it.text.startsWith("/*") }.toList()

val hasBody = expressionStatements.isNotEmpty() || blockComments.isNotEmpty()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// note to self: blockComments only. :120 hasBody considers all comments

Comment thread core/src/main/kotlin/org/jetbrains/ktfmt/format/visitor/Indentation.kt Outdated
@qwwdfsad

Copy link
Copy Markdown
Member

passing it to @kunyavskiy. Cannot do it manually because of GH orgs shenanigans

@AbdullinAM
AbdullinAM requested a review from kunyavskiy August 20, 2026 16:27
@AbdullinAM
AbdullinAM force-pushed the abdullin/call-formatter branch 4 times, most recently from b91f652 to a7b0c49 Compare August 27, 2026 15:39
@AbdullinAM
AbdullinAM force-pushed the abdullin/call-formatter branch from a7b0c49 to dbdc3a4 Compare August 27, 2026 16:04
class Const(val value: Int) : Indentation() {
override val indent: Indent = Indent.Const.make(value, 1)

operator fun plus(other: Const): Const = Const(value + other.value)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably this can be done on demand but this functions can be also in super-class, just by adding/subtracting/multiplying both indents in conditional.
It's also a bit wierd API, that plus/minus accepts other Const, while times accepts int.

But, I'm fine with adding all of this on-demand, espically, if we wouldn't consider this class as public API (should it be internal than?)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of these functions were added on demand, yes

should it be internal than?

It depends in general on whether we consider formatters implementations a public API

* 2. '... = Runnable @Annotation { ... }' due to the annotation
*/
val KtExpression?.scopingLambda: KtLambdaExpression?
internal data class ScopingLambda(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this change in commit about indentations?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed during commit reorg

builder.block(expressionBreakIndent) {
// allows adjusting arguments indentation if a break will be made
val nameTag = BreakTag()
for ((ktExpression, openingGroups, closingGroups, isTrailingLambda, isLast) in

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatting is wierd here

*
* Each group is then emitted one by one to the [builder] while opening and closing groups. Each
* group is opened **before** a corresponding expression is emitted and closed **after**. However,
* if an expression represents a function call, e.g. `doIt(1, 2) { it }`, the group is closed

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to explain why.

@kunyavskiy
kunyavskiy self-requested a review September 1, 2026 14:32
kunyavskiy

This comment was marked as duplicate.

@kunyavskiy kunyavskiy left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I'd say non of my comments above is very important. Feel free to adress them separately in upcoming MRs, if you see it's more convenient for your workflow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants