OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } | |
OLD | NEW |