Skip to content

Conversation

@wsutina
Copy link
Contributor

@wsutina wsutina commented Nov 1, 2024

📝 Description

Updating the RewritingTask to use kotlin-editor, which contains an updated grammar for more complex Kotlin Gradle build scripts. The grammar used for parsing Groovy build scripts remains unchanged.

Note: this depends on cashapp/kotlin-editor#17

@wsutina wsutina changed the title 🚧 Refactor fixDependencies task to use grammar from KotlinEditor for Kotlin Gradle DSL 🚧 Updat Kotlin DSL rewriting functionality to use KotlinEditor Nov 1, 2024
@wsutina wsutina changed the title 🚧 Updat Kotlin DSL rewriting functionality to use KotlinEditor 🚧 Update Kotlin DSL rewriting functionality to use KotlinEditor Nov 1, 2024
@autonomousapps autonomousapps added the enhancement New feature or request label Nov 1, 2024
@autonomousapps autonomousapps self-requested a review November 1, 2024 17:42
@autonomousapps autonomousapps added this to the next milestone Nov 1, 2024
Copy link
Owner

@autonomousapps autonomousapps left a comment

Choose a reason for hiding this comment

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

This is looking really good! Thanks! <3

@wsutina wsutina force-pushed the swipawiwat/kotlin-rewriter branch 2 times, most recently from 529e11a to e71d021 Compare November 6, 2024 07:33
@wsutina wsutina force-pushed the swipawiwat/kotlin-rewriter branch 3 times, most recently from 9327c2b to 8778ec0 Compare November 7, 2024 04:57
@wsutina wsutina changed the title 🚧 Update Kotlin DSL rewriting functionality to use KotlinEditor Update Kotlin DSL rewriting functionality to use KotlinEditor Nov 7, 2024
@wsutina wsutina force-pushed the swipawiwat/kotlin-rewriter branch from 8778ec0 to 510c512 Compare November 7, 2024 05:11
@wsutina wsutina marked this pull request as ready for review November 7, 2024 05:14
@wsutina wsutina force-pushed the swipawiwat/kotlin-rewriter branch from 510c512 to b17b6f3 Compare November 7, 2024 05:18
Copy link
Owner

@autonomousapps autonomousapps left a comment

Choose a reason for hiding this comment

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

Looks great! Thank you <3 Left a few comments.

}

override fun exitNamedBlock(ctx: NamedBlockContext) {
dependencyExtractor.onExitBlock()
Copy link
Owner

Choose a reason for hiding this comment

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

I think the (implied) contract of this function is that it should be at the bottom of the exitNamedBlock function.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Comment on lines 107 to 112
advice.filterToOrderedSet { it.isAnyAdd() }.ifNotEmpty { addAdvice ->
rewriter.insertBefore(
ctx.stop,
addAdvice.joinToString(prefix = "\ndependencies {\n", postfix = "\n}\n", separator = "\n") { a ->
printer.toDeclaration(a)
}
)
}
Copy link
Owner

Choose a reason for hiding this comment

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

This block looks basically identical to the block above, with the exception that this one uses filterToOrderedSet and the above one is just filterToSet. I think We should extract this to a function and use the ordered set function.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Comment on lines 132 to 130
} else if (a.isAnyChange()) {
val configuration = context.primaryExpression()
rewriter.replace(configuration.start, configuration.stop, a.toConfiguration)
}
Copy link
Owner

Choose a reason for hiding this comment

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

I think this is being too clever. The DependencyDeclaration data class has all the information we need, and we shouldn't try to re-parse the context object to get the configuration context out of it. We should just rewrite the whole line using printer.toDeclaration(a). That ensures there's just one method responsible for printing declarations.

I think the above ☝️ is true, but I will note one caveat that came to mind as I wrote it. There are cases where there are really complex dependency declarations, and what I said assumes that DAGP is correctly modeling a declaration in its totality. Your approach is more conservative by just rewriting the configuration name.

All that said, I prefer keeping the code simple and using printer.toDeclaration(a) to rewrite the whole line. fixDependencies is an optional task and is allowed to make assumptions that buildHealth can't.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

. We should just rewrite the whole line using printer.toDeclaration(a). That ensures there's just one method responsible for printing declarations.

Good point. I will update this

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 I'm happy to update this to printer.toDeclaration(a) for simplicity. I was just following the existing pattern e.g.

val c = ctxDependency.configuration
rewriter.replace(c.start, c.stop, a.toConfiguration)

Note on the test set up

After making the change, the test "update dependencies with dependencyMap" test failed e.g. compileOnly(project(:marvin)) (without "") instead of compileOnly(project(":marvin"))

It's because the AdvicePrinter doesn't print the quote if dependencyMap is presented for the specific advice.

return if (!mapped.isNullOrBlank()) {
// If the user is mapping, it's bring-your-own-quotes
mapped
} else {
// If there's no map, include quotes
when (dslKind) {
DslKind.KOTLIN -> "\"$gav\""
DslKind.GROOVY -> "'$gav'"
}

To get the test passing, I need to avoid providing dependencyMap for the dependency we want to remain the same. See change

Question

Can we assume that the given dependencyMap from users should always include quotes?

Copy link
Owner

Choose a reason for hiding this comment

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

Can we assume that the given dependencyMap from users should always include quotes?

Yes. Good catch and fix!

@wsutina wsutina force-pushed the swipawiwat/kotlin-rewriter branch 2 times, most recently from c358cd6 to cf85b18 Compare November 10, 2024 23:31
Copy link
Owner

@autonomousapps autonomousapps left a comment

Choose a reason for hiding this comment

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

LGTM!

Comment on lines 124 to 126
if (it.statement.leafRule() !is PostfixUnaryExpressionContext) return@forEach

val context = it.statement.leafRule() as PostfixUnaryExpressionContext
Copy link
Owner

Choose a reason for hiding this comment

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

This could be simplified a bit into a one-liner:

val context = it.statement.leafRule() as? PostfixUnaryExpressionContext ?: return@forEach

Comment on lines 132 to 130
} else if (a.isAnyChange()) {
val configuration = context.primaryExpression()
rewriter.replace(configuration.start, configuration.stop, a.toConfiguration)
}
Copy link
Owner

Choose a reason for hiding this comment

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

Can we assume that the given dependencyMap from users should always include quotes?

Yes. Good catch and fix!

@autonomousapps
Copy link
Owner

autonomousapps commented Nov 11, 2024

The :buildHealth failure is interesting, and I'll have to think about how to resolve it. The existing antlr support for Groovy deliberately shades antlr to work around common problems with people bringing in different versions of that tool and breaking this plugin. However, now we have KotlinEditor also bringing in antlr. Maybe the most straightforward answer is to shade KotlinEditor as well. Could maybe do it with the extant shadowed/antlr project. 🤔 No, just checked again and that doesn't make sense. I could add a new module just for a shaded version of KotlinEditor. Or I could make the more substantial effort to add Shadow directly to the main module (but this doesn't excite me as a great idea). Or we could even add a shaded version of antlr directly to KotlinEditor -- but I think that's really a user concern and not the responsibility of KotlinEditor.

@autonomousapps autonomousapps force-pushed the swipawiwat/kotlin-rewriter branch from 2cc86a8 to f1f9c94 Compare November 11, 2024 23:05
@autonomousapps autonomousapps merged commit f1f9c94 into autonomousapps:main Nov 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants