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.resolver; | 5 library analyzer.src.generated.resolver; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/token.dart'; | 10 import 'package:analyzer/dart/ast/token.dart'; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 84 * | 84 * |
| 85 * @param errorReporter the error reporter | 85 * @param errorReporter the error reporter |
| 86 */ | 86 */ |
| 87 BestPracticesVerifier( | 87 BestPracticesVerifier( |
| 88 this._errorReporter, TypeProvider typeProvider, this._currentLibrary, | 88 this._errorReporter, TypeProvider typeProvider, this._currentLibrary, |
| 89 {TypeSystem typeSystem}) | 89 {TypeSystem typeSystem}) |
| 90 : _futureNullType = typeProvider.futureNullType, | 90 : _futureNullType = typeProvider.futureNullType, |
| 91 _typeSystem = typeSystem ?? new TypeSystemImpl(); | 91 _typeSystem = typeSystem ?? new TypeSystemImpl(); |
| 92 | 92 |
| 93 @override | 93 @override |
| 94 Object visitAnnotation(Annotation node) { | |
| 95 if (node.elementAnnotation?.isFactory == true) { | |
| 96 AstNode parent = node.parent; | |
| 97 if (parent is MethodDeclaration) { | |
| 98 _checkForInvalidFactory(parent); | |
| 99 } else { | |
| 100 _errorReporter | |
| 101 .reportErrorForNode(HintCode.INVALID_FACTORY_ANNOTATION, node, []); | |
| 102 } | |
| 103 } | |
| 104 return super.visitAnnotation(node); | |
| 105 } | |
| 106 | |
| 107 @override | |
| 94 Object visitArgumentList(ArgumentList node) { | 108 Object visitArgumentList(ArgumentList node) { |
| 95 for (Expression argument in node.arguments) { | 109 for (Expression argument in node.arguments) { |
| 96 ParameterElement parameter = argument.bestParameterElement; | 110 ParameterElement parameter = argument.bestParameterElement; |
| 97 if (parameter?.parameterKind == ParameterKind.POSITIONAL) { | 111 if (parameter?.parameterKind == ParameterKind.POSITIONAL) { |
| 98 _checkForDeprecatedMemberUse(parameter, argument); | 112 _checkForDeprecatedMemberUse(parameter, argument); |
| 99 } | 113 } |
| 100 } | 114 } |
| 101 _checkForArgumentTypesNotAssignableInList(node); | 115 _checkForArgumentTypesNotAssignableInList(node); |
| 102 return super.visitArgumentList(node); | 116 return super.visitArgumentList(node); |
| 103 } | 117 } |
| (...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 667 if (leftType != null && bestRightType != null) { | 681 if (leftType != null && bestRightType != null) { |
| 668 if (!_typeSystem.isAssignableTo(bestRightType, leftType)) { | 682 if (!_typeSystem.isAssignableTo(bestRightType, leftType)) { |
| 669 _errorReporter.reportTypeErrorForNode( | 683 _errorReporter.reportTypeErrorForNode( |
| 670 HintCode.INVALID_ASSIGNMENT, rhs, [bestRightType, leftType]); | 684 HintCode.INVALID_ASSIGNMENT, rhs, [bestRightType, leftType]); |
| 671 return true; | 685 return true; |
| 672 } | 686 } |
| 673 } | 687 } |
| 674 return false; | 688 return false; |
| 675 } | 689 } |
| 676 | 690 |
| 691 void _checkForInvalidFactory(MethodDeclaration decl) { | |
| 692 // Check declaration. | |
| 693 TypeName returnType = decl.returnType; | |
| 694 if (returnType == null || returnType.type is VoidType) { | |
|
Brian Wilkerson
2016/06/24 21:04:00
Checking for `void` makes sense; not sure about ch
pquitslund
2016/06/24 21:40:35
Good point. There could be a pile up, assuming t
| |
| 695 _errorReporter.reportErrorForNode(HintCode.INVALID_FACTORY_METHOD_DECL, | |
| 696 decl.name, [decl.name.toString()]); | |
| 697 return; | |
| 698 } | |
| 699 | |
| 700 // Check implementation. | |
| 701 | |
| 702 FunctionBody body = decl.body; | |
| 703 if (body is EmptyFunctionBody) { | |
| 704 // Abstract methods are OK. | |
| 705 return; | |
| 706 } | |
| 707 | |
| 708 // `new Foo()` or `null`. | |
| 709 bool factoryExpression(Expression expression) => | |
| 710 expression is InstanceCreationExpression || expression is NullLiteral; | |
| 711 | |
| 712 if (body is ExpressionFunctionBody && factoryExpression(body.expression)) { | |
| 713 return; | |
| 714 } else if (body is BlockFunctionBody) { | |
| 715 NodeList<Statement> statements = body.block.statements; | |
| 716 if (statements.isNotEmpty) { | |
| 717 Statement last = statements.last; | |
| 718 if (last is ReturnStatement && factoryExpression(last.expression)) { | |
| 719 return; | |
| 720 } | |
| 721 } | |
| 722 } | |
| 723 | |
| 724 _errorReporter.reportErrorForNode(HintCode.INVALID_FACTORY_METHOD_IMPL, | |
| 725 decl.name, [decl.name.toString()]); | |
| 726 } | |
| 727 | |
| 677 /** | 728 /** |
| 678 * Produces a hint if the given identifier is a protected closure, field or | 729 * Produces a hint if the given identifier is a protected closure, field or |
| 679 * getter/setter, method closure or invocation accessed outside a subclass. | 730 * getter/setter, method closure or invocation accessed outside a subclass. |
| 680 */ | 731 */ |
| 681 void _checkForInvalidProtectedMemberAccess(SimpleIdentifier identifier) { | 732 void _checkForInvalidProtectedMemberAccess(SimpleIdentifier identifier) { |
| 682 if (identifier.inDeclarationContext()) { | 733 if (identifier.inDeclarationContext()) { |
| 683 return; | 734 return; |
| 684 } | 735 } |
| 685 | 736 |
| 686 bool isProtected(Element element) { | 737 bool isProtected(Element element) { |
| (...skipping 10279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10966 return null; | 11017 return null; |
| 10967 } | 11018 } |
| 10968 if (identical(node.staticElement, variable)) { | 11019 if (identical(node.staticElement, variable)) { |
| 10969 if (node.inSetterContext()) { | 11020 if (node.inSetterContext()) { |
| 10970 result = true; | 11021 result = true; |
| 10971 } | 11022 } |
| 10972 } | 11023 } |
| 10973 return null; | 11024 return null; |
| 10974 } | 11025 } |
| 10975 } | 11026 } |
| OLD | NEW |