This repository has been archived by the owner on Jul 16, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 261
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
25 changed files
with
720 additions
and
167 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Long Method | ||
|
||
Long methods are difficult to reuse and understand because they are usually responsible for more than one thing. Separating those methods to several short ones with proper names helps you to reuse your code and understand it better without reading methods body. | ||
|
||
Lines of code with clarification comments usually a sign for possible method extraction because you can name extracted method in a way that will cover comment description and then remove comment. Even comments for one line is a sign for method extraction. | ||
|
||
* To shorten a method, just apply **Extract Method** command. | ||
* If local variables and parameters prevent a method extraction, apply **Replace Temp with Query**, **Introduce Parameter Object** or **Preserve Whole Object** commands. | ||
* Conditional statements or loops indicate the possibility of method extraction. Use **Decompose Conditional** command for conditional expressions and **Extract Method** for loops. | ||
|
||
*** | ||
|
||
P.S. We use terminology from a book **Refactoring Improving the Design of Existing Code** by *Martin Fowler* |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import 'package:analyzer/dart/ast/ast.dart'; | ||
import 'package:meta/meta.dart'; | ||
|
||
import '../models/config.dart'; | ||
import '../models/design_issue.dart'; | ||
|
||
abstract class BasePattern { | ||
final String id; | ||
final Uri documentation; | ||
|
||
const BasePattern({ | ||
@required this.id, | ||
@required this.documentation, | ||
}); | ||
|
||
Iterable<DesignIssue> check( | ||
CompilationUnit unit, Uri sourceUrl, String sourceContent, Config config); | ||
} |
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,66 @@ | ||
import 'package:analyzer/dart/ast/ast.dart'; | ||
import 'package:meta/meta.dart'; | ||
import 'package:source_span/source_span.dart'; | ||
|
||
import '../lines_of_code/lines_with_code_ast_visitor.dart'; | ||
import '../models/config.dart'; | ||
import '../models/design_issue.dart'; | ||
import '../scope_ast_visitor.dart'; | ||
import 'base_pattern.dart'; | ||
|
||
class LongMethod extends BasePattern { | ||
static const String patternId = 'long-method'; | ||
static const _documentationUrl = 'https://git.io/JUIP7'; | ||
|
||
LongMethod() | ||
: super(id: patternId, documentation: Uri.parse(_documentationUrl)); | ||
|
||
@override | ||
Iterable<DesignIssue> check(CompilationUnit unit, Uri sourceUrl, | ||
String sourceContent, Config config) { | ||
final issues = <DesignIssue>[]; | ||
|
||
final visitor = ScopeAstVisitor(); | ||
unit.visitChildren(visitor); | ||
|
||
for (final function in visitor.functions) { | ||
final linesWithCodeAstVisitor = LinesWithCodeAstVisitor(unit.lineInfo); | ||
function.declaration.visitChildren(linesWithCodeAstVisitor); | ||
|
||
if (linesWithCodeAstVisitor.linesWithCode.length > | ||
config.linesOfExecutableCodeWarningLevel) { | ||
final offsetLocation = | ||
unit.lineInfo.getLocation(function.declaration.offset); | ||
final endLocation = unit.lineInfo.getLocation(function.declaration.end); | ||
|
||
issues.add(DesignIssue( | ||
patternId: id, | ||
patternDocumentation: documentation, | ||
sourceSpan: SourceSpanBase( | ||
SourceLocation(function.declaration.offset, | ||
sourceUrl: sourceUrl, | ||
line: offsetLocation.lineNumber, | ||
column: offsetLocation.columnNumber), | ||
SourceLocation(function.declaration.end, | ||
sourceUrl: sourceUrl, | ||
line: endLocation.lineNumber, | ||
column: endLocation.columnNumber), | ||
sourceContent.substring( | ||
function.declaration.offset, function.declaration.end)), | ||
message: _compileMessage( | ||
lines: linesWithCodeAstVisitor.linesWithCode.length), | ||
recommendation: _compileRecomendationMessage( | ||
maximumLines: config.linesOfExecutableCodeWarningLevel), | ||
)); | ||
} | ||
} | ||
|
||
return issues; | ||
} | ||
|
||
String _compileMessage({@required int lines}) => | ||
'Long Method. This method contains $lines lines with executable code.'; | ||
|
||
String _compileRecomendationMessage({@required int maximumLines}) => | ||
"Based on configuration of this package, we don't recommend write a method longer than $maximumLines lines with executable code."; | ||
} |
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,14 @@ | ||
import 'anti_patterns/base_pattern.dart'; | ||
import 'anti_patterns/long_method.dart'; | ||
|
||
final _implementedPatterns = <String, BasePattern Function()>{ | ||
LongMethod.patternId: () => LongMethod(), | ||
}; | ||
|
||
Iterable<BasePattern> get allPatterns => | ||
_implementedPatterns.keys.map((id) => _implementedPatterns[id]()); | ||
|
||
Iterable<BasePattern> getPatternsById(Iterable<String> patternsId) => | ||
List.unmodifiable(_implementedPatterns.keys | ||
.where((id) => patternsId.contains(id)) | ||
.map<BasePattern>((id) => _implementedPatterns[id]())); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import 'package:meta/meta.dart'; | ||
import 'package:source_span/source_span.dart'; | ||
|
||
@immutable | ||
class DesignIssue { | ||
final String patternId; | ||
final Uri patternDocumentation; | ||
final SourceSpanBase sourceSpan; | ||
final String message; | ||
final String recommendation; | ||
|
||
const DesignIssue({ | ||
@required this.patternId, | ||
@required this.patternDocumentation, | ||
@required this.sourceSpan, | ||
@required this.message, | ||
this.recommendation, | ||
}); | ||
} |
Oops, something went wrong.