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

Side by Side Diff: pkg/analyzer/lib/src/generated/resolver.dart

Issue 2096103002: Analyzer support for `@factory` methods (linter#253). (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 5 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.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
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
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
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 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/generated/error.dart ('k') | pkg/analyzer/test/generated/hint_code_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698