Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(260)

Side by Side Diff: lib/src/rules/must_call_super.dart

Issue 1767843002: Lint for `@mustCallSuper` (#194). (Closed) Base URL: https://github.com/dart-lang/linter.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/src/rules.dart ('k') | pubspec.yaml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library linter.src.rules.annotate_overrides; 5 library linter.src.rules.must_call_super;
6 6
7 import 'package:analyzer/dart/element/element.dart'; 7 import 'package:analyzer/dart/element/element.dart';
8 import 'package:analyzer/src/generated/ast.dart'; 8 import 'package:analyzer/src/generated/ast.dart';
9 import 'package:analyzer/src/generated/resolver.dart'; 9 import 'package:analyzer/src/generated/resolver.dart';
10 import 'package:linter/src/linter.dart'; 10 import 'package:linter/src/linter.dart';
11 11
12 const desc = r'Annotate overridden members'; 12 const desc = r'Methods marked @mustCallSuper must invoke super';
13 13
14 const details = r''' 14 const details = r'''
15 **DO** annotate overridden methods and fields. 15 Methods marked `@mustCallSuper` must invoke the overriden super method.
16
17 **DO** ensure that all methods that override a method with the `@mustCallSuper`
18 annotation contain a super invocation of the overridden method.
19
20 The `@mustCallSuper` annotation is implemented in the `meta`
21 [package](https://pub.dartlang.org/packages/meta).
22
23 **BAD:**
24 ```
25 class TestCase {
26 @mustCallSuper
27 void setUp() { ... }
28 }
29
30 class MyTest extends TestCase {
31 @override
32 void setUp() {
33 // do nothing.
34 }
35 ...
36 }
37 ```
16 38
17 **GOOD:** 39 **GOOD:**
18 ``` 40 ```
19 abstract class Dog { 41 class TestCase {
20 String get breed; 42 @mustCallSuper
21 void bark() {} 43 void setUp() { ... }
22 } 44 }
23 45
24 class Husky extends Dog { 46 class MyTest extends TestCase {
25 @override 47 @override
26 final String breed = 'Husky'; 48 void setUp() {
27 @override 49 super.setUp();
28 void bark() {} 50 }
29 } 51 }
30 ``` 52 ```
31 53
32 **BAD:** 54 ''';
33 ``` 55
34 class Cat { 56 class InvocationCollector extends RecursiveAstVisitor {
35 int get lives => 9; 57 final List<String> superCalls = <String>[];
58
59 @override
60 visitMethodInvocation(MethodInvocation node) {
61 if (node.target is SuperExpression) {
62 superCalls.add(node.methodName.name);
63 }
64 }
36 } 65 }
37 66
38 class Lucky extends Cat { 67 class MustCallSuper extends LintRule {
39 final int lives = 14; 68 MustCallSuper()
40 }
41 ```
42 ''';
43
44 class AnnotateOverrides extends LintRule {
45 AnnotateOverrides()
46 : super( 69 : super(
47 name: 'annotate_overrides', 70 name: 'must_call_super',
48 description: desc, 71 description: desc,
49 details: details, 72 details: details,
50 group: Group.style); 73 group: Group.style);
51 74
52 @override 75 @override
53 AstVisitor getVisitor() => new Visitor(this); 76 AstVisitor getVisitor() => new Visitor(this);
54 } 77 }
55 78
56 class Visitor extends SimpleAstVisitor { 79 class Visitor extends SimpleAstVisitor {
57 InheritanceManager manager; 80 InheritanceManager manager;
(...skipping 14 matching lines...) Expand all
72 return manager.lookupInheritance(classElement, member.name); 95 return manager.lookupInheritance(classElement, member.name);
73 } 96 }
74 97
75 @override 98 @override
76 visitCompilationUnit(CompilationUnit node) { 99 visitCompilationUnit(CompilationUnit node) {
77 LibraryElement library = node?.element?.library; 100 LibraryElement library = node?.element?.library;
78 manager = library == null ? null : new InheritanceManager(library); 101 manager = library == null ? null : new InheritanceManager(library);
79 } 102 }
80 103
81 @override 104 @override
82 visitFieldDeclaration(FieldDeclaration node) {
83 for (VariableDeclaration field in node.fields.variables) {
84 if (field?.element != null && !field.element.isOverride) {
85 ExecutableElement member = getOverriddenMember(field.element);
86 if (member != null) {
87 rule.reportLint(field);
88 }
89 }
90 }
91 }
92
93 @override
94 visitMethodDeclaration(MethodDeclaration node) { 105 visitMethodDeclaration(MethodDeclaration node) {
95 if (node?.element != null && !node.element.isOverride) { 106 ExecutableElement overriddenMember = getOverriddenMember(node.element);
96 ExecutableElement member = getOverriddenMember(node.element); 107 if (overriddenMember != null) {
97 if (member != null) { 108 InvocationCollector collector = new InvocationCollector();
109 node.accept(collector);
110 if (!collector.superCalls.contains(overriddenMember.name)) {
98 rule.reportLint(node.name); 111 rule.reportLint(node.name);
99 } 112 }
100 } 113 }
101 } 114 }
102 } 115 }
OLDNEW
« no previous file with comments | « lib/src/rules.dart ('k') | pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698