-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/master'
- Loading branch information
Showing
28 changed files
with
694 additions
and
299 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
125 changes: 125 additions & 0 deletions
125
lib/src/lints/avoid_debug_print/avoid_debug_print_rule.dart
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,125 @@ | ||
import 'package:analyzer/dart/ast/ast.dart'; | ||
import 'package:analyzer/dart/ast/syntactic_entity.dart'; | ||
import 'package:analyzer/error/listener.dart'; | ||
import 'package:custom_lint_builder/custom_lint_builder.dart'; | ||
import 'package:solid_lints/src/lints/avoid_debug_print/models/avoid_debug_print_func_model.dart'; | ||
import 'package:solid_lints/src/models/rule_config.dart'; | ||
import 'package:solid_lints/src/models/solid_lint_rule.dart'; | ||
|
||
/// A `avoid_debug_print` rule which forbids calling or referencing | ||
/// debugPrint function from flutter/foundation. | ||
/// | ||
/// ### Example | ||
/// | ||
/// #### BAD: | ||
/// | ||
/// ```dart | ||
/// debugPrint(''); // LINT | ||
/// var ref = debugPrint; // LINT | ||
/// var ref2; | ||
/// ref2 = debugPrint; // LINT | ||
/// ``` | ||
/// | ||
/// #### GOOD: | ||
/// | ||
/// ```dart | ||
/// log(''); | ||
/// ``` | ||
class AvoidDebugPrint extends SolidLintRule { | ||
/// The [LintCode] of this lint rule that represents | ||
/// the error when debugPrint is called | ||
static const lintName = 'avoid_debug_print'; | ||
|
||
AvoidDebugPrint._(super.config); | ||
|
||
/// Creates a new instance of [AvoidDebugPrint] | ||
/// based on the lint configuration. | ||
factory AvoidDebugPrint.createRule(CustomLintConfigs configs) { | ||
final rule = RuleConfig( | ||
configs: configs, | ||
name: lintName, | ||
problemMessage: (_) => "Avoid using 'debugPrint'", | ||
); | ||
|
||
return AvoidDebugPrint._(rule); | ||
} | ||
|
||
@override | ||
void run( | ||
CustomLintResolver resolver, | ||
ErrorReporter reporter, | ||
CustomLintContext context, | ||
) { | ||
context.registry.addFunctionExpressionInvocation( | ||
(node) { | ||
final func = node.function; | ||
if (func is! Identifier) { | ||
return; | ||
} | ||
_checkIdentifier( | ||
identifier: func, | ||
node: node, | ||
reporter: reporter, | ||
); | ||
}, | ||
); | ||
|
||
// addFunctionReference does not get triggered. | ||
// addVariableDeclaration and addAssignmentExpression | ||
// are used as a workaround for simple cases | ||
|
||
context.registry.addVariableDeclaration((node) { | ||
_handleVariableAssignmentDeclaration( | ||
node: node, | ||
reporter: reporter, | ||
); | ||
}); | ||
|
||
context.registry.addAssignmentExpression((node) { | ||
_handleVariableAssignmentDeclaration( | ||
node: node, | ||
reporter: reporter, | ||
); | ||
}); | ||
} | ||
|
||
/// Checks whether the function identifier satisfies conditions | ||
void _checkIdentifier({ | ||
required Identifier identifier, | ||
required AstNode node, | ||
required ErrorReporter reporter, | ||
}) { | ||
final funcModel = AvoidDebugPrintFuncModel.parseExpression(identifier); | ||
|
||
if (funcModel.hasSameName && funcModel.hasTheSameSource) { | ||
reporter.reportErrorForNode(code, node); | ||
} | ||
} | ||
|
||
/// Returns null if doesnt have right operand | ||
SyntacticEntity? _getRightOperand(List<SyntacticEntity> entities) { | ||
/// Example var t = 15; 15 is in 3d position | ||
if (entities.length < 3) { | ||
return null; | ||
} | ||
return entities[2]; | ||
} | ||
|
||
/// Handles variable assignment and declaration | ||
void _handleVariableAssignmentDeclaration({ | ||
required AstNode node, | ||
required ErrorReporter reporter, | ||
}) { | ||
final rightOperand = _getRightOperand(node.childEntities.toList()); | ||
|
||
if (rightOperand == null || rightOperand is! Identifier) { | ||
return; | ||
} | ||
|
||
_checkIdentifier( | ||
identifier: rightOperand, | ||
node: node, | ||
reporter: reporter, | ||
); | ||
} | ||
} |
61 changes: 61 additions & 0 deletions
61
lib/src/lints/avoid_debug_print/models/avoid_debug_print_func_model.dart
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,61 @@ | ||
import 'package:analyzer/dart/ast/ast.dart'; | ||
|
||
/// A class used to parse function expression | ||
class AvoidDebugPrintFuncModel { | ||
/// Function name | ||
final String name; | ||
|
||
/// Function's source path | ||
final String sourcePath; | ||
|
||
/// A class used to parse function expression | ||
const AvoidDebugPrintFuncModel({ | ||
required this.name, | ||
required this.sourcePath, | ||
}); | ||
|
||
/// A constructor that parses identifier into [name] and [sourcePath] | ||
factory AvoidDebugPrintFuncModel.parseExpression( | ||
Identifier identifier, | ||
) { | ||
switch (identifier) { | ||
case PrefixedIdentifier(): | ||
final prefix = identifier.prefix.name; | ||
return AvoidDebugPrintFuncModel( | ||
name: identifier.name.replaceAll('$prefix.', ''), | ||
sourcePath: | ||
identifier.staticElement?.librarySource?.uri.toString() ?? '', | ||
); | ||
case SimpleIdentifier(): | ||
return AvoidDebugPrintFuncModel( | ||
name: identifier.name, | ||
sourcePath: | ||
identifier.staticElement?.librarySource?.uri.toString() ?? '', | ||
); | ||
default: | ||
return AvoidDebugPrintFuncModel._empty(); | ||
} | ||
} | ||
|
||
factory AvoidDebugPrintFuncModel._empty() { | ||
return const AvoidDebugPrintFuncModel( | ||
name: '', | ||
sourcePath: '', | ||
); | ||
} | ||
|
||
static const String _printPath = 'package:flutter/src/foundation/print.dart'; | ||
|
||
static const String _debugPrint = 'debugPrint'; | ||
|
||
/// Ehether the function has the same source library as debugPrint func | ||
bool get hasTheSameSource => _printPath == sourcePath; | ||
|
||
/// Ehether the function has the same name as debugPrint | ||
bool get hasSameName => _debugPrint == name; | ||
|
||
@override | ||
String toString() { | ||
return '$name, $sourcePath'; | ||
} | ||
} |
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
Oops, something went wrong.