Skip to content

Commit

Permalink
Refactored code and reorganized files
Browse files Browse the repository at this point in the history
  • Loading branch information
Yarl745 committed Apr 17, 2024
1 parent ea4c93d commit 117ec97
Show file tree
Hide file tree
Showing 11 changed files with 94 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,14 @@ class AvoidLateKeywordRule extends SolidLintRule<AvoidLateKeywordParameters> {
}

bool _hasIgnoredType(VariableDeclaration node) {
final ignoredTypes = config.parameters.ignoredTypes.toSet();
if (ignoredTypes.isEmpty) return false;

final variableType = node.declaredElement?.type;
if (variableType == null) return false;

return variableType.hasIgnoredType(
ignoredTypes: config.parameters.ignoredTypes.toSet(),
ignoredTypes: ignoredTypes,
);
}
}
66 changes: 66 additions & 0 deletions lib/src/utils/named_type_utils.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import 'package:analyzer/dart/analysis/utilities.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';

/// Parses the provided type string to extract a [NamedType].
NamedType parseNamedTypeFromString(String typeString) {
try {
final namedTypeFinder = _NamedTypeFinder();

final parseResult = parseString(content: "$typeString _;");
parseResult.unit.visitChildren(namedTypeFinder);

return namedTypeFinder.foundNamedType!;
} catch (_) {
throw Exception("No NamedType could be parsed from the input "
"typeString: '$typeString'. Ensure it's a valid Dart "
"type declaration.");
}
}

class _NamedTypeFinder extends GeneralizingAstVisitor<void> {
NamedType? _foundNamedType;

NamedType? get foundNamedType => _foundNamedType;

@override
void visitNamedType(NamedType namedType) {
_foundNamedType ??= namedType;
}
}

///
extension ChildNamedTypes on NamedType {
/// Retrieves child [NamedType] instances from type arguments.
List<NamedType> get childNamedTypes =>
typeArguments?.arguments.whereType<NamedType>().toList() ?? [];

/// Gets the token name of this type instance.
String get tokenName => name2.toString();

/// Checks if the current token name is 'dynamic'.
bool get isDynamic => tokenName == "dynamic";

/// Checks if the current token name is 'Object'.
bool get isObject => tokenName == "Object";

/// Checks if this node is a subtype of the specified node
/// based on their structures.
bool isSubtypeOf({required NamedType node}) {
if (isDynamic || isObject) return true;

if (tokenName != node.tokenName) return false;

if (childNamedTypes.isEmpty) return true;

if (childNamedTypes.length != node.childNamedTypes.length) return false;

for (int i = 0; i < childNamedTypes.length; i++) {
if (!childNamedTypes[i].isSubtypeOf(node: node.childNamedTypes[i])) {
return false;
}
}

return true;
}
}
65 changes: 0 additions & 65 deletions lib/src/utils/node_utils.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import 'package:analyzer/dart/analysis/utilities.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';

/// Check node is override method from its metadata
bool isOverride(List<Annotation> metadata) => metadata.any(
Expand All @@ -24,66 +22,3 @@ String humanReadableNodeType(AstNode? node) {

return 'Node';
}

/// Parses the provided type string to extract a [NamedType].
NamedType parseNamedTypeFromString(String typeString) {
try {
final namedTypeFinder = _NamedTypeFinder();

final parseResult = parseString(content: "$typeString _;");
parseResult.unit.visitChildren(namedTypeFinder);

return namedTypeFinder.foundNamedType!;
} catch (_) {
throw Exception("No NamedType could be parsed from the input "
"typeString: '$typeString'. Ensure it's a valid Dart "
"type declaration.");
}
}

class _NamedTypeFinder extends GeneralizingAstVisitor<void> {
NamedType? _foundNamedType;

NamedType? get foundNamedType => _foundNamedType;

@override
void visitNamedType(NamedType namedType) {
_foundNamedType ??= namedType;
}
}

///
extension ChildNamedTypes on NamedType {
/// Retrieves child [NamedType] instances from type arguments.
List<NamedType> get childNamedTypes =>
typeArguments?.arguments.whereType<NamedType>().toList() ?? [];

/// Gets the token name of this type instance.
String get tokenName => name2.toString();

/// Checks if the current token name is 'dynamic'.
bool get isDynamic => tokenName == "dynamic";

/// Checks if the current token name is 'Object'.
bool get isObject => tokenName == "Object";

/// Checks if this node is a subtype of the specified node
/// based on their structures.
bool isSubtype({required NamedType node}) {
if (isDynamic || isObject) return true;

if (tokenName != node.tokenName) return false;

if (childNamedTypes.isEmpty) return true;

if (childNamedTypes.length != node.childNamedTypes.length) return false;

for (int i = 0; i < childNamedTypes.length; i++) {
if (!childNamedTypes[i].isSubtype(node: node.childNamedTypes[i])) {
return false;
}
}

return true;
}
}
6 changes: 2 additions & 4 deletions lib/src/utils/types_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:collection/collection.dart';
import 'package:solid_lints/src/utils/node_utils.dart';
import 'package:solid_lints/src/utils/named_type_utils.dart';

extension Subtypes on DartType {
Iterable<DartType> get supertypes {
Expand Down Expand Up @@ -67,7 +67,7 @@ extension Subtypes on DartType {

for (final ignoredTypeNode in ignoredTypeNodes) {
for (final checkedTypeNode in checkedTypeNodes) {
if (ignoredTypeNode.isSubtype(node: checkedTypeNode)) {
if (ignoredTypeNode.isSubtypeOf(node: checkedTypeNode)) {
return true;
}
}
Expand All @@ -80,8 +80,6 @@ extension Subtypes on DartType {
extension TypeString on String {
static final _genericRegex = RegExp('<.*>');

bool get hasGenericString => contains(_genericRegex);

String replaceGenericString() => replaceFirst(_genericRegex, '');
}

Expand Down
6 changes: 0 additions & 6 deletions lint_test/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,6 @@ custom_lint:
- avoid_non_null_assertion
- avoid_late_keyword:
allow_initialized: true
ignored_types:
- ColorTween
- AnimationController
- Subscription<List<Object?>>
- Subscription<Map<dynamic, String>>
- Subscription<ConcreteTypeWithNoGenerics>
- avoid_global_state
- avoid_returning_widgets
- avoid_unnecessary_setstate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@ class Subscription<T> {}

class ConcreteTypeWithNoGenerics {}

class NotAllowed {}

/// Check "late" keyword fail
///
/// `avoid_late_keyword`
/// allow_initialized option disabled
class AvoidLateKeyword {
/// expect_lint: avoid_late_keyword
late final NotAllowed na1;

late final Subscription subscription1;

late final Subscription<ConcreteTypeWithNoGenerics> subscription2;
Expand All @@ -21,6 +26,9 @@ class AvoidLateKeyword {
late final Subscription<Map<dynamic, String>> subscription5;

void test() {
/// expect_lint: avoid_late_keyword
late final NotAllowed na1;

late final Subscription subscription1;

late final Subscription<ConcreteTypeWithNoGenerics> subscription2;
Expand Down
14 changes: 14 additions & 0 deletions lint_test/avoid_late_keyword/with_generics/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
analyzer:
plugins:
- ../custom_lint

custom_lint:
rules:
- avoid_late_keyword:
allow_initialized: true
ignored_types:
- ColorTween
- AnimationController
- Subscription<List<Object?>>
- Subscription<Map<dynamic, String>>
- Subscription<ConcreteTypeWithNoGenerics>
File renamed without changes.

0 comments on commit 117ec97

Please sign in to comment.