forked from mrmans0n/compose-rules
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
160f555
commit 5bb9ee3
Showing
6 changed files
with
164 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
97 changes: 97 additions & 0 deletions
97
rules/ktlint/src/main/kotlin/io/nlopez/compose/rules/ktlint/EnforceIconTextButtonRule.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package io.nlopez.compose.rules.ktlint | ||
|
||
import com.pinterest.ktlint.rule.engine.core.api.ElementType | ||
import com.pinterest.ktlint.rule.engine.core.api.Rule | ||
import com.pinterest.ktlint.rule.engine.core.api.RuleId | ||
import com.pinterest.ktlint.rule.engine.core.api.editorconfig.EditorConfig | ||
import org.jetbrains.kotlin.com.intellij.lang.ASTNode | ||
import org.jetbrains.kotlin.psi.KtCallExpression | ||
import org.jetbrains.kotlin.psi.KtPsiFactory | ||
import org.jetbrains.kotlin.psi.psiUtil.startOffset | ||
|
||
/** | ||
* Custom ktlint rule to enforce the use of IconTextButton instead of Button to maintain consistency across the UI. | ||
* | ||
* Maintainer: My stc Team | ||
* Repository URL: https://github.com/your-repository-url | ||
* Issue Tracker: https://github.com/your-repository-url/issues | ||
* | ||
* ## Non-Compliant Example: | ||
* ``` | ||
* @Composable | ||
* fun Example() { | ||
* Button(onClick = { /* Do something */ }) { | ||
* Text("Click Me") | ||
* } | ||
* } | ||
* ``` | ||
* | ||
* ## Compliant Example: | ||
* ``` | ||
* @Composable | ||
* fun Example() { | ||
* IconTextButton(onClick = { /* Do something */ }) { | ||
* Text("Click Me") | ||
* } | ||
* } | ||
* ``` | ||
*/ | ||
class EnforceIconTextButtonRule : | ||
Rule( | ||
ruleId = RuleId("enforce-icon-text-button"), | ||
about = | ||
About( | ||
maintainer = "My stc Team", | ||
repositoryUrl = "https://github.com/your-repository-url", | ||
issueTrackerUrl = "https://github.com/your-repository-url/issues", | ||
), | ||
) { | ||
override fun beforeFirstNode(editorConfig: EditorConfig) { | ||
// Reset state before processing the file. | ||
} | ||
|
||
@Deprecated( | ||
"Marked for removal in Ktlint 2.0. Please implement interface RuleAutocorrectApproveHandler.", | ||
) | ||
override fun beforeVisitChildNodes( | ||
node: ASTNode, | ||
autoCorrect: Boolean, | ||
emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit, | ||
) { | ||
val psi = node.psi | ||
when (node.elementType) { | ||
ElementType.CALL_EXPRESSION -> { | ||
val callExpression = psi as? KtCallExpression ?: return | ||
visitCallExpression(callExpression, autoCorrect, emit) | ||
} | ||
} | ||
} | ||
|
||
private fun visitCallExpression( | ||
callExpression: KtCallExpression, | ||
autoCorrect: Boolean, | ||
emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit, | ||
) { | ||
val calleeExpression = callExpression.calleeExpression?.text ?: return | ||
|
||
// Check if the call expression is a Button composable. | ||
if (calleeExpression == "Button") { | ||
emit( | ||
callExpression.startOffset, | ||
"Use IconTextButton instead of Button to maintain consistency in the UI.", | ||
autoCorrect, | ||
) | ||
|
||
// Optional auto-correct logic to replace Button with IconTextButton | ||
if (autoCorrect) { | ||
replaceButtonWithIconTextButton(callExpression) | ||
} | ||
} | ||
} | ||
|
||
private fun replaceButtonWithIconTextButton(callExpression: KtCallExpression) { | ||
val factory = KtPsiFactory(callExpression.project) | ||
val newCallee = factory.createExpression("IconTextButton") | ||
callExpression.calleeExpression?.replace(newCallee) | ||
} | ||
} |
62 changes: 62 additions & 0 deletions
62
rules/ktlint/src/main/kotlin/io/nlopez/compose/rules/ktlint/EnforceIconTextButtonRule22.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package io.nlopez.compose.rules.ktlint | ||
|
||
import io.nlopez.compose.rules.KtlintRule | ||
import com.pinterest.ktlint.rule.engine.core.api.AutocorrectDecision | ||
import com.pinterest.ktlint.rule.engine.core.api.editorconfig.EditorConfig | ||
import io.nlopez.compose.core.ComposeKtVisitor | ||
import io.nlopez.compose.core.Decision | ||
import io.nlopez.compose.core.Emitter | ||
import org.jetbrains.kotlin.com.intellij.lang.ASTNode | ||
import org.jetbrains.kotlin.psi.KtCallExpression | ||
import org.jetbrains.kotlin.psi.psiUtil.startOffset | ||
|
||
class EnforceIconTextButtonRule22 : | ||
KtlintRule( | ||
id = "compose:enforce-icon-text-button", | ||
editorConfigProperties = emptySet(), | ||
), ComposeKtVisitor { | ||
private lateinit var properties: EditorConfig | ||
|
||
override fun beforeFirstNode(editorConfig: EditorConfig) { | ||
properties = editorConfig | ||
} | ||
|
||
override fun beforeVisitChildNodes( | ||
node: ASTNode, | ||
emit: ( | ||
offset: Int, | ||
errorMessage: String, | ||
canBeAutoCorrected: Boolean, | ||
) -> AutocorrectDecision, | ||
) { | ||
val psi = node.psi | ||
if (psi is KtCallExpression) { | ||
visitCallExpression(psi, emit.toEmitter()) | ||
} | ||
} | ||
|
||
private fun visitCallExpression( | ||
callExpression: KtCallExpression, | ||
emitter: Emitter, | ||
) { | ||
val calleeExpression = callExpression.calleeExpression?.text ?: return | ||
|
||
// Check if the call expression is a Button composable. | ||
if (calleeExpression == "Button") { | ||
emitter.report( | ||
callExpression, | ||
"Use IconTextButton instead of Button to maintain consistency in the UI.", | ||
canBeAutoCorrected = true, | ||
) | ||
} | ||
} | ||
|
||
private fun ((Int, String, Boolean) -> AutocorrectDecision).toEmitter() = | ||
Emitter { element, errorMessage, canBeAutoCorrected -> | ||
val offset = element.startOffset | ||
when (invoke(offset, errorMessage, canBeAutoCorrected)) { | ||
AutocorrectDecision.ALLOW_AUTOCORRECT -> Decision.Fix | ||
AutocorrectDecision.NO_AUTOCORRECT -> Decision.Ignore | ||
} | ||
} | ||
} |