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

Unified Diff: pkg/analyzer/lib/src/generated/error_verifier.dart

Issue 1773803002: Validation of `@mustCallSuper` overrides. (Closed) Base URL: git@github.com:dart-lang/sdk.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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/analyzer/lib/src/generated/error.dart ('k') | pkg/analyzer/test/generated/resolver_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/generated/error_verifier.dart
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 463e9165f7f3e26fe5b6ac9f0352c28bd6e19ca7..1fef4df5e9716c07a4d982426528872ddb9e7140 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -896,6 +896,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
_checkForAllInvalidOverrideErrorCodesForMethod(node);
_checkForTypeAnnotationDeferredClass(returnTypeName);
_checkForIllegalReturnType(returnTypeName);
+ _checkForMustCallSuper(node);
return super.visitMethodDeclaration(node);
} finally {
_enclosingFunction = previousFunction;
@@ -4416,6 +4417,25 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
return numSuperInitializers > 0;
}
+ void _checkForMustCallSuper(MethodDeclaration node) {
+ ExecutableElement overriddenMember = _getOverriddenMember(node.element);
+ while (overriddenMember is MethodElement) {
+ for (ElementAnnotation annotation in overriddenMember.metadata) {
+ if (annotation.isMustCallSuper) {
+ _InvocationCollector collector = new _InvocationCollector();
+ node.accept(collector);
+ if (!collector.superCalls.contains(overriddenMember.name)) {
+ _errorReporter.reportErrorForNode(HintCode.MUST_CALL_SUPER,
+ node.name, [overriddenMember.enclosingElement.name]);
+ return;
Brian Wilkerson 2016/03/07 21:07:09 I think this 'return' wants to be in the outer 'if
pquitslund 2016/03/07 21:29:39 Good catch and good idea. Updating.
+ }
+ }
+ }
+ // Keep looking up the chain.
+ overriddenMember = _getOverriddenMember(overriddenMember);
+ }
+ }
+
/**
* Checks to ensure that the given native function [body] is in SDK code.
*
@@ -5837,6 +5857,19 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
}
}
+ ExecutableElement _getOverriddenMember(Element member) {
+ if (member == null || _inheritanceManager == null) {
+ return null;
+ }
+
+ ClassElement classElement =
+ member.getAncestor((element) => element is ClassElement);
+ if (classElement == null) {
+ return null;
+ }
+ return _inheritanceManager.lookupInheritance(classElement, member.name);
+ }
+
/**
* Return the type of the first and only parameter of the given [setter].
*/
@@ -6220,3 +6253,17 @@ class GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference
}
}
}
+
+/**
+ * Recursively visits an AST, looking for method invocations.
+ */
+class _InvocationCollector extends RecursiveAstVisitor {
+ final List<String> superCalls = <String>[];
+
+ @override
+ visitMethodInvocation(MethodInvocation node) {
+ if (node.target is SuperExpression) {
+ superCalls.add(node.methodName.name);
+ }
+ }
+}
« no previous file with comments | « pkg/analyzer/lib/src/generated/error.dart ('k') | pkg/analyzer/test/generated/resolver_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698