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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 analyzer.src.generated.error_verifier; 5 library analyzer.src.generated.error_verifier;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 import "dart:math" as math; 8 import "dart:math" as math;
9 9
10 import 'package:analyzer/dart/ast/ast.dart'; 10 import 'package:analyzer/dart/ast/ast.dart';
(...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after
889 _checkForConflictingStaticSetterAndInstanceMember(node); 889 _checkForConflictingStaticSetterAndInstanceMember(node);
890 } else if (node.isOperator) { 890 } else if (node.isOperator) {
891 _checkForOptionalParameterInOperator(node); 891 _checkForOptionalParameterInOperator(node);
892 _checkForWrongNumberOfParametersForOperator(node); 892 _checkForWrongNumberOfParametersForOperator(node);
893 _checkForNonVoidReturnTypeForOperator(node); 893 _checkForNonVoidReturnTypeForOperator(node);
894 } 894 }
895 _checkForConcreteClassWithAbstractMember(node); 895 _checkForConcreteClassWithAbstractMember(node);
896 _checkForAllInvalidOverrideErrorCodesForMethod(node); 896 _checkForAllInvalidOverrideErrorCodesForMethod(node);
897 _checkForTypeAnnotationDeferredClass(returnTypeName); 897 _checkForTypeAnnotationDeferredClass(returnTypeName);
898 _checkForIllegalReturnType(returnTypeName); 898 _checkForIllegalReturnType(returnTypeName);
899 _checkForMustCallSuper(node);
899 return super.visitMethodDeclaration(node); 900 return super.visitMethodDeclaration(node);
900 } finally { 901 } finally {
901 _enclosingFunction = previousFunction; 902 _enclosingFunction = previousFunction;
902 _isInStaticMethod = false; 903 _isInStaticMethod = false;
903 } 904 }
904 } 905 }
905 906
906 @override 907 @override
907 Object visitMethodInvocation(MethodInvocation node) { 908 Object visitMethodInvocation(MethodInvocation node) {
908 Expression target = node.realTarget; 909 Expression target = node.realTarget;
(...skipping 3500 matching lines...) Expand 10 before | Expand all | Expand 10 after
4409 numSuperInitializers++; 4410 numSuperInitializers++;
4410 if (numSuperInitializers > 1) { 4411 if (numSuperInitializers > 1) {
4411 _errorReporter.reportErrorForNode( 4412 _errorReporter.reportErrorForNode(
4412 CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, initializer); 4413 CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, initializer);
4413 } 4414 }
4414 } 4415 }
4415 } 4416 }
4416 return numSuperInitializers > 0; 4417 return numSuperInitializers > 0;
4417 } 4418 }
4418 4419
4420 void _checkForMustCallSuper(MethodDeclaration node) {
4421 ExecutableElement overriddenMember = _getOverriddenMember(node.element);
4422 while (overriddenMember is MethodElement) {
4423 for (ElementAnnotation annotation in overriddenMember.metadata) {
4424 if (annotation.isMustCallSuper) {
4425 _InvocationCollector collector = new _InvocationCollector();
4426 node.accept(collector);
4427 if (!collector.superCalls.contains(overriddenMember.name)) {
4428 _errorReporter.reportErrorForNode(HintCode.MUST_CALL_SUPER,
4429 node.name, [overriddenMember.enclosingElement.name]);
4430 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.
4431 }
4432 }
4433 }
4434 // Keep looking up the chain.
4435 overriddenMember = _getOverriddenMember(overriddenMember);
4436 }
4437 }
4438
4419 /** 4439 /**
4420 * Checks to ensure that the given native function [body] is in SDK code. 4440 * Checks to ensure that the given native function [body] is in SDK code.
4421 * 4441 *
4422 * See [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE]. 4442 * See [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE].
4423 */ 4443 */
4424 bool _checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody body) { 4444 bool _checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody body) {
4425 if (!_isInSystemLibrary && !_hasExtUri) { 4445 if (!_isInSystemLibrary && !_hasExtUri) {
4426 _errorReporter.reportErrorForNode( 4446 _errorReporter.reportErrorForNode(
4427 ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, body); 4447 ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, body);
4428 return true; 4448 return true;
(...skipping 1401 matching lines...) Expand 10 before | Expand all | Expand 10 after
5830 */ 5850 */
5831 DartType _getGetterType(PropertyAccessorElement getter) { 5851 DartType _getGetterType(PropertyAccessorElement getter) {
5832 FunctionType functionType = getter.type; 5852 FunctionType functionType = getter.type;
5833 if (functionType != null) { 5853 if (functionType != null) {
5834 return functionType.returnType; 5854 return functionType.returnType;
5835 } else { 5855 } else {
5836 return null; 5856 return null;
5837 } 5857 }
5838 } 5858 }
5839 5859
5860 ExecutableElement _getOverriddenMember(Element member) {
5861 if (member == null || _inheritanceManager == null) {
5862 return null;
5863 }
5864
5865 ClassElement classElement =
5866 member.getAncestor((element) => element is ClassElement);
5867 if (classElement == null) {
5868 return null;
5869 }
5870 return _inheritanceManager.lookupInheritance(classElement, member.name);
5871 }
5872
5840 /** 5873 /**
5841 * Return the type of the first and only parameter of the given [setter]. 5874 * Return the type of the first and only parameter of the given [setter].
5842 */ 5875 */
5843 DartType _getSetterType(PropertyAccessorElement setter) { 5876 DartType _getSetterType(PropertyAccessorElement setter) {
5844 // Get the parameters for MethodDeclaration or FunctionDeclaration 5877 // Get the parameters for MethodDeclaration or FunctionDeclaration
5845 List<ParameterElement> setterParameters = setter.parameters; 5878 List<ParameterElement> setterParameters = setter.parameters;
5846 // If there are no setter parameters, return no type. 5879 // If there are no setter parameters, return no type.
5847 if (setterParameters.length == 0) { 5880 if (setterParameters.length == 0) {
5848 return null; 5881 return null;
5849 } 5882 }
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
6213 toCheck.add(type.element); 6246 toCheck.add(type.element);
6214 // type arguments 6247 // type arguments
6215 if (type is InterfaceType) { 6248 if (type is InterfaceType) {
6216 InterfaceType interfaceType = type; 6249 InterfaceType interfaceType = type;
6217 for (DartType typeArgument in interfaceType.typeArguments) { 6250 for (DartType typeArgument in interfaceType.typeArguments) {
6218 _addTypeToCheck(typeArgument); 6251 _addTypeToCheck(typeArgument);
6219 } 6252 }
6220 } 6253 }
6221 } 6254 }
6222 } 6255 }
6256
6257 /**
6258 * Recursively visits an AST, looking for method invocations.
6259 */
6260 class _InvocationCollector extends RecursiveAstVisitor {
6261 final List<String> superCalls = <String>[];
6262
6263 @override
6264 visitMethodInvocation(MethodInvocation node) {
6265 if (node.target is SuperExpression) {
6266 superCalls.add(node.methodName.name);
6267 }
6268 }
6269 }
OLDNEW
« 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