Chromium Code Reviews| 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 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 811 bool wasInConstInstanceCreation = _isInConstInstanceCreation; | 811 bool wasInConstInstanceCreation = _isInConstInstanceCreation; |
| 812 _isInConstInstanceCreation = node.isConst; | 812 _isInConstInstanceCreation = node.isConst; |
| 813 try { | 813 try { |
| 814 ConstructorName constructorName = node.constructorName; | 814 ConstructorName constructorName = node.constructorName; |
| 815 TypeName typeName = constructorName.type; | 815 TypeName typeName = constructorName.type; |
| 816 DartType type = typeName.type; | 816 DartType type = typeName.type; |
| 817 if (type is InterfaceType) { | 817 if (type is InterfaceType) { |
| 818 InterfaceType interfaceType = type; | 818 InterfaceType interfaceType = type; |
| 819 _checkForConstOrNewWithAbstractClass(node, typeName, interfaceType); | 819 _checkForConstOrNewWithAbstractClass(node, typeName, interfaceType); |
| 820 _checkForConstOrNewWithEnum(node, typeName, interfaceType); | 820 _checkForConstOrNewWithEnum(node, typeName, interfaceType); |
| 821 _checkForMissingRequiredParam( | |
| 822 node.staticElement?.type, node.argumentList, node.constructorName); | |
| 821 if (_isInConstInstanceCreation) { | 823 if (_isInConstInstanceCreation) { |
| 822 _checkForConstWithNonConst(node); | 824 _checkForConstWithNonConst(node); |
| 823 _checkForConstWithUndefinedConstructor( | 825 _checkForConstWithUndefinedConstructor( |
| 824 node, constructorName, typeName); | 826 node, constructorName, typeName); |
| 825 _checkForConstWithTypeParameters(typeName); | 827 _checkForConstWithTypeParameters(typeName); |
| 826 _checkForConstDeferredClass(node, constructorName, typeName); | 828 _checkForConstDeferredClass(node, constructorName, typeName); |
| 827 } else { | 829 } else { |
| 828 _checkForNewWithUndefinedConstructor(node, constructorName, typeName); | 830 _checkForNewWithUndefinedConstructor(node, constructorName, typeName); |
| 829 } | 831 } |
| 830 } | 832 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 922 Object visitMethodInvocation(MethodInvocation node) { | 924 Object visitMethodInvocation(MethodInvocation node) { |
| 923 Expression target = node.realTarget; | 925 Expression target = node.realTarget; |
| 924 SimpleIdentifier methodName = node.methodName; | 926 SimpleIdentifier methodName = node.methodName; |
| 925 if (target != null) { | 927 if (target != null) { |
| 926 ClassElement typeReference = ElementResolver.getTypeReference(target); | 928 ClassElement typeReference = ElementResolver.getTypeReference(target); |
| 927 _checkForStaticAccessToInstanceMember(typeReference, methodName); | 929 _checkForStaticAccessToInstanceMember(typeReference, methodName); |
| 928 _checkForInstanceAccessToStaticMember(typeReference, methodName); | 930 _checkForInstanceAccessToStaticMember(typeReference, methodName); |
| 929 } else { | 931 } else { |
| 930 _checkForUnqualifiedReferenceToNonLocalStaticMember(methodName); | 932 _checkForUnqualifiedReferenceToNonLocalStaticMember(methodName); |
| 931 } | 933 } |
| 934 _checkForMissingRequiredParam( | |
| 935 node.staticInvokeType, node.argumentList, methodName); | |
| 932 return super.visitMethodInvocation(node); | 936 return super.visitMethodInvocation(node); |
| 933 } | 937 } |
| 934 | 938 |
| 935 @override | 939 @override |
| 936 Object visitNativeClause(NativeClause node) { | 940 Object visitNativeClause(NativeClause node) { |
| 937 // TODO(brianwilkerson) Figure out the right rule for when 'native' is | 941 // TODO(brianwilkerson) Figure out the right rule for when 'native' is |
| 938 // allowed. | 942 // allowed. |
| 939 if (!_isInSystemLibrary) { | 943 if (!_isInSystemLibrary) { |
| 940 _errorReporter.reportErrorForNode( | 944 _errorReporter.reportErrorForNode( |
| 941 ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE, node); | 945 ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE, node); |
| (...skipping 2776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3718 if (!executableElement.isStatic) { | 3722 if (!executableElement.isStatic) { |
| 3719 return; | 3723 return; |
| 3720 } | 3724 } |
| 3721 | 3725 |
| 3722 _errorReporter.reportErrorForNode( | 3726 _errorReporter.reportErrorForNode( |
| 3723 StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, | 3727 StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, |
| 3724 name, | 3728 name, |
| 3725 [name.name]); | 3729 [name.name]); |
| 3726 } | 3730 } |
| 3727 | 3731 |
| 3732 void _checkForMissingRequiredParam( | |
| 3733 DartType type, ArgumentList argumentList, AstNode node) { | |
| 3734 if (type is FunctionType) { | |
| 3735 List<ParameterElement> parameters = type.parameters; | |
| 3736 for (ParameterElement param in parameters) { | |
| 3737 if (param.parameterKind == ParameterKind.NAMED) { | |
| 3738 ElementAnnotationImpl annotation = _getRequiredAnnotation(param); | |
| 3739 if (annotation != null) { | |
| 3740 String paramName = param.name; | |
| 3741 if (!_containsNamedExpression(argumentList, paramName)) { | |
| 3742 String reason = ''; | |
| 3743 DartObject constantValue = annotation.constantValue; | |
| 3744 reason ??= constantValue.getField('reason')?.toStringValue(); | |
|
Brian Wilkerson
2016/04/05 23:27:35
reason will never be null at this point, so I thin
pquitslund
2016/04/06 00:04:13
Right. Thanks for catching that.
| |
| 3745 // Append a `.` if needed. | |
| 3746 if (reason != null && | |
| 3747 reason.isNotEmpty && | |
| 3748 !reason.endsWith('.')) { | |
| 3749 reason += '.'; | |
| 3750 } | |
| 3751 | |
| 3752 _errorReporter.reportErrorForNode( | |
| 3753 HintCode.MISSING_REQUIRED_PARAM, node, [paramName, reason]); | |
| 3754 } | |
| 3755 } | |
| 3756 } | |
| 3757 } | |
| 3758 } | |
| 3759 } | |
| 3760 | |
| 3761 ElementAnnotationImpl _getRequiredAnnotation(ParameterElement param) => param | |
| 3762 .metadata | |
| 3763 .firstWhere((ElementAnnotation e) => e.isRequired, orElse: () => null); | |
| 3764 | |
| 3765 bool _containsNamedExpression(ArgumentList args, String name) { | |
| 3766 for (Expression expression in args.arguments) { | |
| 3767 if (expression is NamedExpression) { | |
| 3768 if (expression.name.label.name == name) { | |
| 3769 return true; | |
| 3770 } | |
| 3771 } | |
| 3772 } | |
| 3773 return false; | |
| 3774 } | |
| 3775 | |
| 3728 /** | 3776 /** |
| 3729 * Check whether the given [executableElement] collides with the name of a | 3777 * Check whether the given [executableElement] collides with the name of a |
| 3730 * static method in one of its superclasses, and reports the appropriate | 3778 * static method in one of its superclasses, and reports the appropriate |
| 3731 * warning if it does. The [errorNameTarget] is the node to report problems | 3779 * warning if it does. The [errorNameTarget] is the node to report problems |
| 3732 * on. | 3780 * on. |
| 3733 * | 3781 * |
| 3734 * See [StaticTypeWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_ST ATIC]. | 3782 * See [StaticTypeWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_ST ATIC]. |
| 3735 */ | 3783 */ |
| 3736 bool _checkForInstanceMethodNameCollidesWithSuperclassStatic( | 3784 bool _checkForInstanceMethodNameCollidesWithSuperclassStatic( |
| 3737 ExecutableElement executableElement, SimpleIdentifier errorNameTarget) { | 3785 ExecutableElement executableElement, SimpleIdentifier errorNameTarget) { |
| (...skipping 2324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6062 class _InvocationCollector extends RecursiveAstVisitor { | 6110 class _InvocationCollector extends RecursiveAstVisitor { |
| 6063 final List<String> superCalls = <String>[]; | 6111 final List<String> superCalls = <String>[]; |
| 6064 | 6112 |
| 6065 @override | 6113 @override |
| 6066 visitMethodInvocation(MethodInvocation node) { | 6114 visitMethodInvocation(MethodInvocation node) { |
| 6067 if (node.target is SuperExpression) { | 6115 if (node.target is SuperExpression) { |
| 6068 superCalls.add(node.methodName.name); | 6116 superCalls.add(node.methodName.name); |
| 6069 } | 6117 } |
| 6070 } | 6118 } |
| 6071 } | 6119 } |
| OLD | NEW |