Last active
March 6, 2023 09:48
-
-
Save MarcinusX/9548f66251c4784aeb2de5eeaa7c9da5 to your computer and use it in GitHub Desktop.
Revisions
-
MarcinusX revised this gist
Mar 6, 2023 . 1 changed file with 4 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -85,7 +85,10 @@ extension on MethodInvocation { bool get isFromTimestamp => targetType != null && TypeChecker.fromName( 'Timestamp', packageName: 'cheddar_api', ).isAssignableFromType(targetType!); bool get isToDateTime => methodName.name == 'toDateTime'; -
MarcinusX created this gist
Feb 28, 2023 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,106 @@ import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer/error/error.dart'; import 'package:analyzer/error/listener.dart'; import 'package:analyzer/source/source_range.dart'; import 'package:custom_lint_builder/custom_lint_builder.dart'; class PreferTimestampsToLocalDateTimes extends DartLintRule { PreferTimestampsToLocalDateTimes() : super(code: _code); static const _code = LintCode( name: 'timestamp_to_date_time_is_local', problemMessage: 'Parsing Timestamp to DateTime should always be to local time', ); @override void run( CustomLintResolver resolver, ErrorReporter reporter, CustomLintContext context, ) { context.registry.addMethodInvocation((node) { if (node.isFromTimestamp && node.isToDateTime && !node.hasArgumentToLocalSetToTrue) { reporter.reportErrorForNode(_code, node); } }); } @override List<Fix> getFixes() => [_AddIsLocalFix()]; } class _AddIsLocalFix extends DartFix { @override void run( CustomLintResolver resolver, ChangeReporter reporter, CustomLintContext context, AnalysisError analysisError, List<AnalysisError> others, ) { context.registry.addMethodInvocation((node) { if (!analysisError.sourceRange.intersects(node.sourceRange) || !node.isFromTimestamp && !node.isToDateTime) { return; } final leftParenthesisOffset = node.argumentList.leftParenthesis.offset; final rightParenthesisOffset = node.argumentList.rightParenthesis.offset; final fix = 'toLocal: true'; if (node.hasArgumentToLocalSetToFalse) { final changeBuilder = reporter.createChangeBuilder( message: 'Replace with "toLocal: true"', priority: 1, ); changeBuilder.addDartFileEdit((builder) { builder.addSimpleReplacement( SourceRange( leftParenthesisOffset + 1, rightParenthesisOffset - leftParenthesisOffset - 1, ), fix, ); }); } else { final changeBuilder = reporter.createChangeBuilder( message: 'Add "toLocal: true"', priority: 1, ); changeBuilder.addDartFileEdit((builder) { builder.addSimpleInsertion( leftParenthesisOffset + 1, fix, ); }); } }); } } extension on MethodInvocation { DartType? get targetType => target?.staticType; bool get isFromTimestamp => targetType != null && TypeChecker.fromName('Timestamp').isAssignableFromType(targetType!); bool get isToDateTime => methodName.name == 'toDateTime'; bool get hasArgumentToLocalSetToTrue => hasArgumentToLocalSetToValue(true); bool get hasArgumentToLocalSetToFalse => hasArgumentToLocalSetToValue(false); bool hasArgumentToLocalSetToValue(bool value) => argumentList.arguments.any((argument) => argument is NamedExpression && argument.name.label.name == 'toLocal' && argument.expression.isBooleanWithValue(value)); } extension on Expression { bool isBooleanWithValue(bool value) => this is BooleanLiteral && (this as BooleanLiteral).value == value; }