Compose Lint — Android¶
Architecture¶
Le module fram-a11y-lint est un module Gradle Java/Kotlin qui enregistre 7 détecteurs UAST analysant l'arbre syntaxique Kotlin en temps réel.
compose-lint/
├── build.gradle.kts
└── src/
├── main/java/com/fram/lint/
│ ├── A11yLintRegistry.kt ← Registre central
│ └── checks/
│ ├── IconContentDescriptionDetector.kt ← SKILL-01
│ ├── HardcodedColorDetector.kt ← SKILL-02
│ ├── FixedTextSizeDetector.kt ← SKILL-03
│ ├── ClickableWithoutSemanticsDetector.kt ← SKILL-05
│ ├── TextFieldWithoutLabelDetector.kt ← SKILL-09
│ ├── NavigationSemanticsDetector.kt ← SKILL-10
│ └── TouchTargetDetector.kt ← SKILL-11
└── test/java/com/fram/lint/
└── A11yLintChecksTest.kt ← 10 tests unitaires
Installation¶
Détecteurs¶
IconContentDescriptionDetector — SKILL-01¶
| Issue ID | Sévérité | Détecte |
|---|---|---|
IconMissingContentDescription | Error | Icon() sans contentDescription |
EmptyContentDescription | Error | contentDescription = "" (vide ≠ null) |
RedundantContentDescriptionPrefix | Warning | contentDescription commençant par "image de" |
Exemple de détection
// ❌ Déclenche IconMissingContentDescription
Icon(Icons.Default.Warning) // (1)
// ✅ Correct — décoratif
Icon(Icons.Default.Star, contentDescription = null)
// ✅ Correct — informatif
Icon(Icons.Default.Warning, contentDescription = "Attention")
- TalkBack lit "Warning" (nom de la ressource) au lieu d'une description utile.
ClickableWithoutSemanticsDetector — SKILL-05¶
| Issue ID | Sévérité | Détecte |
|---|---|---|
ClickableWithoutSemantics | Error | Modifier.clickable sans semantics |
ClickableMissingRole | Warning | semantics sans role |
EmptySemanticsContentDescription | Error | contentDescription = "" dans semantics |
Smart exclusion
Les composables Material3 natifs (Button, IconButton, TextButton, OutlinedButton) sont automatiquement exclus — ils ont la sémantique intégrée.
HardcodedColorDetector — SKILL-02¶
| Issue ID | Sévérité | Détecte |
|---|---|---|
HardcodedAccessibilityColor | Warning | Color(0xFF...) hors MaterialTheme |
ColorOnlyStatusCommunication | Warning | Color.Red / Color.Green sans icône |
Fichiers de thème exclus
Les fichiers contenant "Theme", "Color", "Colors" ou "Palette" dans leur nom sont automatiquement ignorés.
FixedTextSizeDetector — SKILL-03¶
| Issue ID | Sévérité | Détecte |
|---|---|---|
FixedTextSizeDp | Warning | fontSize en dp au lieu de sp |
TextFieldWithoutLabelDetector — SKILL-09¶
| Issue ID | Sévérité | Détecte |
|---|---|---|
TextFieldMissingLabel | Error | TextField/OutlinedTextField sans label |
TextFieldEmptyLabel | Error | label = { Text("") } vide |
NavigationSemanticsDetector — SKILL-10¶
| Issue ID | Sévérité | Détecte |
|---|---|---|
MissingScreenTitle | Warning | Scaffold sans topBar ni heading() |
TouchTargetDetector — SKILL-11¶
| Issue ID | Sévérité | Détecte |
|---|---|---|
SmallTouchTarget | Warning | Zone de touche < 48dp |
Auto-fix
Ajouter .minimumInteractiveComponentSize() dans la chaîne Modifier pour garantir 48dp.
Tests¶
Les 10 tests vérifient :
- Détection correcte des violations
- Absence de faux positifs sur le code correct
- Exclusion des composables Material3 natifs