| 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'; |
| 11 import 'package:analyzer/dart/ast/token.dart'; | 11 import 'package:analyzer/dart/ast/token.dart'; |
| 12 import 'package:analyzer/dart/ast/visitor.dart'; | 12 import 'package:analyzer/dart/ast/visitor.dart'; |
| 13 import 'package:analyzer/dart/element/element.dart'; | 13 import 'package:analyzer/dart/element/element.dart'; |
| 14 import 'package:analyzer/dart/element/type.dart'; | 14 import 'package:analyzer/dart/element/type.dart'; |
| 15 import 'package:analyzer/dart/element/visitor.dart'; | 15 import 'package:analyzer/dart/element/visitor.dart'; |
| 16 import 'package:analyzer/src/dart/ast/token.dart'; | 16 import 'package:analyzer/src/dart/ast/token.dart'; |
| 17 import 'package:analyzer/src/dart/ast/utilities.dart'; |
| 17 import 'package:analyzer/src/dart/element/element.dart'; | 18 import 'package:analyzer/src/dart/element/element.dart'; |
| 18 import 'package:analyzer/src/dart/element/member.dart'; | 19 import 'package:analyzer/src/dart/element/member.dart'; |
| 19 import 'package:analyzer/src/dart/element/type.dart'; | 20 import 'package:analyzer/src/dart/element/type.dart'; |
| 20 import 'package:analyzer/src/generated/constant.dart'; | 21 import 'package:analyzer/src/generated/constant.dart'; |
| 21 import 'package:analyzer/src/generated/element_resolver.dart'; | 22 import 'package:analyzer/src/generated/element_resolver.dart'; |
| 22 import 'package:analyzer/src/generated/error.dart'; | 23 import 'package:analyzer/src/generated/error.dart'; |
| 23 import 'package:analyzer/src/generated/java_engine.dart'; | 24 import 'package:analyzer/src/generated/java_engine.dart'; |
| 24 import 'package:analyzer/src/generated/parser.dart' | 25 import 'package:analyzer/src/generated/parser.dart' |
| 25 show Parser, ParserErrorCode; | 26 show Parser, ParserErrorCode; |
| 26 import 'package:analyzer/src/generated/resolver.dart'; | 27 import 'package:analyzer/src/generated/resolver.dart'; |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 _isInStaticMethod = false; | 299 _isInStaticMethod = false; |
| 299 _boolType = _typeProvider.boolType; | 300 _boolType = _typeProvider.boolType; |
| 300 _intType = _typeProvider.intType; | 301 _intType = _typeProvider.intType; |
| 301 _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT = _typeProvider.nonSubtypableTypes; | 302 _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT = _typeProvider.nonSubtypableTypes; |
| 302 _typeSystem = _currentLibrary.context.typeSystem; | 303 _typeSystem = _currentLibrary.context.typeSystem; |
| 303 } | 304 } |
| 304 | 305 |
| 305 @override | 306 @override |
| 306 Object visitAnnotation(Annotation node) { | 307 Object visitAnnotation(Annotation node) { |
| 307 _checkForInvalidAnnotationFromDeferredLibrary(node); | 308 _checkForInvalidAnnotationFromDeferredLibrary(node); |
| 309 _checkForMissingJSLibAnnotation(node); |
| 308 return super.visitAnnotation(node); | 310 return super.visitAnnotation(node); |
| 309 } | 311 } |
| 310 | 312 |
| 311 @override | 313 @override |
| 312 Object visitArgumentList(ArgumentList node) { | 314 Object visitArgumentList(ArgumentList node) { |
| 313 _checkForArgumentTypesNotAssignableInList(node); | 315 _checkForArgumentTypesNotAssignableInList(node); |
| 314 return super.visitArgumentList(node); | 316 return super.visitArgumentList(node); |
| 315 } | 317 } |
| 316 | 318 |
| 317 @override | 319 @override |
| (...skipping 3404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3722 if (!executableElement.isStatic) { | 3724 if (!executableElement.isStatic) { |
| 3723 return; | 3725 return; |
| 3724 } | 3726 } |
| 3725 | 3727 |
| 3726 _errorReporter.reportErrorForNode( | 3728 _errorReporter.reportErrorForNode( |
| 3727 StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, | 3729 StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, |
| 3728 name, | 3730 name, |
| 3729 [name.name]); | 3731 [name.name]); |
| 3730 } | 3732 } |
| 3731 | 3733 |
| 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 DartObject constantValue = annotation.constantValue; | |
| 3743 String reason = | |
| 3744 constantValue.getField('reason')?.toStringValue() ?? ''; | |
| 3745 _errorReporter.reportErrorForNode( | |
| 3746 HintCode.MISSING_REQUIRED_PARAM, node, [paramName, reason]); | |
| 3747 } | |
| 3748 } | |
| 3749 } | |
| 3750 } | |
| 3751 } | |
| 3752 } | |
| 3753 | |
| 3754 ElementAnnotationImpl _getRequiredAnnotation(ParameterElement param) => param | |
| 3755 .metadata | |
| 3756 .firstWhere((ElementAnnotation e) => e.isRequired, orElse: () => null); | |
| 3757 | |
| 3758 bool _containsNamedExpression(ArgumentList args, String name) { | |
| 3759 for (Expression expression in args.arguments) { | |
| 3760 if (expression is NamedExpression) { | |
| 3761 if (expression.name.label.name == name) { | |
| 3762 return true; | |
| 3763 } | |
| 3764 } | |
| 3765 } | |
| 3766 return false; | |
| 3767 } | |
| 3768 | |
| 3769 /** | 3734 /** |
| 3770 * Check whether the given [executableElement] collides with the name of a | 3735 * Check whether the given [executableElement] collides with the name of a |
| 3771 * static method in one of its superclasses, and reports the appropriate | 3736 * static method in one of its superclasses, and reports the appropriate |
| 3772 * warning if it does. The [errorNameTarget] is the node to report problems | 3737 * warning if it does. The [errorNameTarget] is the node to report problems |
| 3773 * on. | 3738 * on. |
| 3774 * | 3739 * |
| 3775 * See [StaticTypeWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_ST
ATIC]. | 3740 * See [StaticTypeWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_ST
ATIC]. |
| 3776 */ | 3741 */ |
| 3777 bool _checkForInstanceMethodNameCollidesWithSuperclassStatic( | 3742 bool _checkForInstanceMethodNameCollidesWithSuperclassStatic( |
| 3778 ExecutableElement executableElement, SimpleIdentifier errorNameTarget) { | 3743 ExecutableElement executableElement, SimpleIdentifier errorNameTarget) { |
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4235 int offset = statement.offset; | 4200 int offset = statement.offset; |
| 4236 int end = statement.rightParenthesis.end; | 4201 int end = statement.rightParenthesis.end; |
| 4237 _errorReporter.reportErrorForOffset( | 4202 _errorReporter.reportErrorForOffset( |
| 4238 StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH, | 4203 StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH, |
| 4239 offset, | 4204 offset, |
| 4240 end - offset, | 4205 end - offset, |
| 4241 [constantNames[i]]); | 4206 [constantNames[i]]); |
| 4242 } | 4207 } |
| 4243 } | 4208 } |
| 4244 | 4209 |
| 4210 void _checkForMissingJSLibAnnotation(Annotation node) { |
| 4211 if (node.elementAnnotation.isJS) { |
| 4212 Element element = ElementLocator.locate(node.parent); |
| 4213 if (element?.library?.isJS != true) { |
| 4214 _errorReporter.reportErrorForNode( |
| 4215 HintCode.MISSING_JS_LIB_ANNOTATION, node, [element.name]); |
| 4216 } |
| 4217 } |
| 4218 } |
| 4219 |
| 4220 void _checkForMissingRequiredParam( |
| 4221 DartType type, ArgumentList argumentList, AstNode node) { |
| 4222 if (type is FunctionType) { |
| 4223 List<ParameterElement> parameters = type.parameters; |
| 4224 for (ParameterElement param in parameters) { |
| 4225 if (param.parameterKind == ParameterKind.NAMED) { |
| 4226 ElementAnnotationImpl annotation = _getRequiredAnnotation(param); |
| 4227 if (annotation != null) { |
| 4228 String paramName = param.name; |
| 4229 if (!_containsNamedExpression(argumentList, paramName)) { |
| 4230 DartObject constantValue = annotation.constantValue; |
| 4231 String reason = |
| 4232 constantValue.getField('reason')?.toStringValue() ?? ''; |
| 4233 _errorReporter.reportErrorForNode( |
| 4234 HintCode.MISSING_REQUIRED_PARAM, node, [paramName, reason]); |
| 4235 } |
| 4236 } |
| 4237 } |
| 4238 } |
| 4239 } |
| 4240 } |
| 4241 |
| 4245 /** | 4242 /** |
| 4246 * Verify that the given function [body] does not contain return statements | 4243 * Verify that the given function [body] does not contain return statements |
| 4247 * that both have and do not have return values. | 4244 * that both have and do not have return values. |
| 4248 * | 4245 * |
| 4249 * See [StaticWarningCode.MIXED_RETURN_TYPES]. | 4246 * See [StaticWarningCode.MIXED_RETURN_TYPES]. |
| 4250 */ | 4247 */ |
| 4251 void _checkForMixedReturns(BlockFunctionBody body) { | 4248 void _checkForMixedReturns(BlockFunctionBody body) { |
| 4252 if (_hasReturnWithoutValue) { | 4249 if (_hasReturnWithoutValue) { |
| 4253 return; | 4250 return; |
| 4254 } | 4251 } |
| (...skipping 1393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5648 } | 5645 } |
| 5649 } | 5646 } |
| 5650 DartType staticReturnType = getStaticType(returnExpression); | 5647 DartType staticReturnType = getStaticType(returnExpression); |
| 5651 if (staticReturnType != null && _enclosingFunction.isAsynchronous) { | 5648 if (staticReturnType != null && _enclosingFunction.isAsynchronous) { |
| 5652 return _typeProvider.futureType.instantiate( | 5649 return _typeProvider.futureType.instantiate( |
| 5653 <DartType>[staticReturnType.flattenFutures(_typeSystem)]); | 5650 <DartType>[staticReturnType.flattenFutures(_typeSystem)]); |
| 5654 } | 5651 } |
| 5655 return staticReturnType; | 5652 return staticReturnType; |
| 5656 } | 5653 } |
| 5657 | 5654 |
| 5655 bool _containsNamedExpression(ArgumentList args, String name) { |
| 5656 for (Expression expression in args.arguments) { |
| 5657 if (expression is NamedExpression) { |
| 5658 if (expression.name.label.name == name) { |
| 5659 return true; |
| 5660 } |
| 5661 } |
| 5662 } |
| 5663 return false; |
| 5664 } |
| 5665 |
| 5658 MethodElement _findOverriddenMemberThatMustCallSuper(MethodDeclaration node) { | 5666 MethodElement _findOverriddenMemberThatMustCallSuper(MethodDeclaration node) { |
| 5659 ExecutableElement overriddenMember = _getOverriddenMember(node.element); | 5667 ExecutableElement overriddenMember = _getOverriddenMember(node.element); |
| 5660 List<ExecutableElement> seen = <ExecutableElement>[]; | 5668 List<ExecutableElement> seen = <ExecutableElement>[]; |
| 5661 while ( | 5669 while ( |
| 5662 overriddenMember is MethodElement && !seen.contains(overriddenMember)) { | 5670 overriddenMember is MethodElement && !seen.contains(overriddenMember)) { |
| 5663 for (ElementAnnotation annotation in overriddenMember.metadata) { | 5671 for (ElementAnnotation annotation in overriddenMember.metadata) { |
| 5664 if (annotation.isMustCallSuper) { | 5672 if (annotation.isMustCallSuper) { |
| 5665 return overriddenMember; | 5673 return overriddenMember; |
| 5666 } | 5674 } |
| 5667 } | 5675 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5728 } | 5736 } |
| 5729 | 5737 |
| 5730 ClassElement classElement = | 5738 ClassElement classElement = |
| 5731 member.getAncestor((element) => element is ClassElement); | 5739 member.getAncestor((element) => element is ClassElement); |
| 5732 if (classElement == null) { | 5740 if (classElement == null) { |
| 5733 return null; | 5741 return null; |
| 5734 } | 5742 } |
| 5735 return _inheritanceManager.lookupInheritance(classElement, member.name); | 5743 return _inheritanceManager.lookupInheritance(classElement, member.name); |
| 5736 } | 5744 } |
| 5737 | 5745 |
| 5746 ElementAnnotationImpl _getRequiredAnnotation(ParameterElement param) => param |
| 5747 .metadata |
| 5748 .firstWhere((ElementAnnotation e) => e.isRequired, orElse: () => null); |
| 5749 |
| 5738 /** | 5750 /** |
| 5739 * Return the type of the first and only parameter of the given [setter]. | 5751 * Return the type of the first and only parameter of the given [setter]. |
| 5740 */ | 5752 */ |
| 5741 DartType _getSetterType(PropertyAccessorElement setter) { | 5753 DartType _getSetterType(PropertyAccessorElement setter) { |
| 5742 // Get the parameters for MethodDeclaration or FunctionDeclaration | 5754 // Get the parameters for MethodDeclaration or FunctionDeclaration |
| 5743 List<ParameterElement> setterParameters = setter.parameters; | 5755 List<ParameterElement> setterParameters = setter.parameters; |
| 5744 // If there are no setter parameters, return no type. | 5756 // If there are no setter parameters, return no type. |
| 5745 if (setterParameters.length == 0) { | 5757 if (setterParameters.length == 0) { |
| 5746 return null; | 5758 return null; |
| 5747 } | 5759 } |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6103 class _InvocationCollector extends RecursiveAstVisitor { | 6115 class _InvocationCollector extends RecursiveAstVisitor { |
| 6104 final List<String> superCalls = <String>[]; | 6116 final List<String> superCalls = <String>[]; |
| 6105 | 6117 |
| 6106 @override | 6118 @override |
| 6107 visitMethodInvocation(MethodInvocation node) { | 6119 visitMethodInvocation(MethodInvocation node) { |
| 6108 if (node.target is SuperExpression) { | 6120 if (node.target is SuperExpression) { |
| 6109 superCalls.add(node.methodName.name); | 6121 superCalls.add(node.methodName.name); |
| 6110 } | 6122 } |
| 6111 } | 6123 } |
| 6112 } | 6124 } |
| OLD | NEW |