Migrate/proper super calls#229
Conversation
There was a problem hiding this comment.
Code Review
This pull request refactors the solid_lints package to utilize the analysis_server_plugin and migrates several lint rules—AvoidDebugPrintInReleaseRule, AvoidGlobalStateRule, and ProperSuperCallsRule—to a visitor-based architecture. It also introduces a new test suite for these rules. Review feedback highlights that ProperSuperCallsRule is missing its import and registration in the main plugin file. Additionally, there are recommendations to improve the detection logic in AvoidDebugPrintInReleaseRule by replacing unreliable string-based URI and expression checks with more robust AST and element resolution.
I am having trouble creating individual review comments. Click here to see my feedback.
lib/main.dart (4)
The import for ProperSuperCallsRule is missing, which is required for its registration.
import 'package:solid_lints/src/lints/avoid_global_state/avoid_global_state_rule.dart';
import 'package:solid_lints/src/lints/proper_super_calls/proper_super_calls_rule.dart';
lib/main.dart (21-28)
The ProperSuperCallsRule is not registered in the plugin. Given the PR title specifically mentions this rule, it should be included in the register method.
void register(PluginRegistry registry) {
registry.registerLintRule(
AvoidGlobalStateRule(),
);
registry.registerLintRule(
AvoidDebugPrintInReleaseRule(),
);
registry.registerLintRule(
ProperSuperCallsRule(),
);
}lib/src/lints/avoid_debug_print_in_release/visitors/avoid_debug_print_in_release_visitor.dart (39-41)
The check sourceUri.contains(_foundationUri) will likely fail for standard Flutter usage. debugPrint is defined in package:flutter/src/foundation/print.dart, which does not contain the string package:flutter/foundation.dart. A more robust check would be to verify if the URI starts with package:flutter/ and contains foundation.
final isFlutterFoundation = sourceUri.startsWith('package:flutter/') &&
sourceUri.contains('foundation');
lib/src/lints/avoid_debug_print_in_release/visitors/avoid_debug_print_in_release_visitor.dart (58)
Using toString().contains() on an expression is unreliable for logic as it can lead to false negatives (e.g., if a variable name happens to contain the substring). It is better to inspect the AST nodes and resolve the elements to ensure they refer to the expected constants from the Flutter foundation library.
| import 'package:solid_lints/src/lints/avoid_debug_print_in_release/avoid_debug_print_in_release_rule.dart'; | ||
|
|
||
| /// Visitor for [AvoidDebugPrintInReleaseRule]. | ||
| class AvoidDebugPrintInReleaseVisitor extends SimpleAstVisitor<void> { |
There was a problem hiding this comment.
I do not think it should be in this PR.
| final hasOverride = node.metadata.any( | ||
| (annotation) => annotation.name.name == _override, | ||
| ); | ||
| if (!hasOverride) return; |
There was a problem hiding this comment.
It would be great if we could check if this method overrides Flutter's State class.
| @override | ||
| LintCode get diagnosticCode => _superInitStateCode; |
There was a problem hiding this comment.
I see we are repeating the same statements from rule to rule. It would be great if we could have something as we did before - SolidLintRule. It would allow us to get rid of boilerplate code and make our code cleaner.
| onViolation: (nameToken, {required bool isInitState}) { | ||
| // Access the reporter from the currentUnit | ||
| final reporter = context.currentUnit?.diagnosticReporter; | ||
|
|
||
| reporter?.atToken( | ||
| nameToken, | ||
| isInitState ? _superInitStateCode : _superDisposeCode, | ||
| ); |
There was a problem hiding this comment.
Why are we passing this logic as a closure? Does it make sense to encapsulate it in the visitor as we do for all other rules?
| String get analysisRule => ProperSuperCallsRule.lintName; | ||
|
|
||
| /// Mocks the Flutter framework parts relevant to this lint. | ||
| String get _flutterBase => r''' |
There was a problem hiding this comment.
| String get _flutterBase => r''' | |
| String get _flutterWidgetImplementation => r''' |
|
|
||
| void test_initState_reports_when_not_first() async { | ||
| await assertDiagnostics( | ||
| _flutterBase + |
There was a problem hiding this comment.
Use dependency mocking instead, as you did for the avoid_debug_print rule tests.
| } | ||
| ''', | ||
| [ | ||
| lint(197, 9), // Highlights 'initState' |
There was a problem hiding this comment.
| lint(197, 9), // Highlights 'initState' | |
| lint(197, 9), |
Please, remove unnecessary comments.
| '''); | ||
| } | ||
| } |
There was a problem hiding this comment.
I believe we miss some test cases here:
- rule should not assert when we are not overriding the method.
- rule should assert when we do override, but omit explicit
@overridedeclaration.
Also, please think of edge cases and add more tests.
0ac062d to
5aa35df
Compare
04a0112
into
analysis_server_migration
No description provided.