run method
void
run(
- CustomLintResolver resolver,
- DiagnosticReporter reporter,
- CustomLintContext context
Emits lints for a given file.
run will only be invoked with files respecting filesToAnalyze
Implementation
@override
void run(
CustomLintResolver resolver,
DiagnosticReporter reporter,
CustomLintContext context,
) {
context.registry.addInstanceCreationExpression((node) {
final type = node.staticType;
if (type == null) {
return;
}
final typeName = type.element?.name;
// Check for images and icons that should have semantic labels
final imageTypes = [
'Image',
'Icon',
'SvgPicture', // from flutter_svg package
];
if (!imageTypes.contains(typeName)) {
return;
}
bool hasSemanticLabel = false;
bool isExcludedFromSemantics = false;
// Check if semanticLabel or excludeFromSemantics is provided
for (final arg in node.argumentList.arguments) {
if (arg is NamedExpression) {
final paramName = arg.name.label.name;
if (paramName == 'semanticLabel') {
// Check if the value is not null or empty string
final expr = arg.expression;
if (expr is! NullLiteral) {
if (expr is SimpleStringLiteral) {
hasSemanticLabel = expr.value.isNotEmpty;
} else {
// Assume non-literal values are valid
hasSemanticLabel = true;
}
}
}
if (paramName == 'excludeFromSemantics') {
final expr = arg.expression;
if (expr is BooleanLiteral && expr.value) {
isExcludedFromSemantics = true;
}
}
}
}
// Check for parent tooltip or ExcludeSemantics wrapper
final hasTooltip = hasParentTooltip(node);
final semanticInfo = getSemanticWrappingInfo(node);
// Report if no semantic label, no tooltip, not excluded, not wrapped in ExcludeSemantics,
// and not wrapped in Semantics with label
if (!hasSemanticLabel &&
!isExcludedFromSemantics &&
!hasTooltip &&
!semanticInfo.isExcluded &&
!semanticInfo.hasSemantics) {
reporter.atNode(node, code);
}
});
}