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

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: Allow decls w/o a return type. 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 // Note that null return types are expected to be flagged by other analyses.
694 DartType returnType = decl.returnType?.type;
695 if (returnType is VoidType) {
696 _errorReporter.reportErrorForNode(HintCode.INVALID_FACTORY_METHOD_DECL,
697 decl.name, [decl.name.toString()]);
698 return;
699 }
700
701 // Check implementation.
702
703 FunctionBody body = decl.body;
704 if (body is EmptyFunctionBody) {
705 // Abstract methods are OK.
706 return;
707 }
708
709 // `new Foo()` or `null`.
710 bool factoryExpression(Expression expression) =>
711 expression is InstanceCreationExpression || expression is NullLiteral;
712
713 if (body is ExpressionFunctionBody && factoryExpression(body.expression)) {
714 return;
715 } else if (body is BlockFunctionBody) {
716 NodeList<Statement> statements = body.block.statements;
717 if (statements.isNotEmpty) {
718 Statement last = statements.last;
719 if (last is ReturnStatement && factoryExpression(last.expression)) {
720 return;
721 }
722 }
723 }
724
725 _errorReporter.reportErrorForNode(HintCode.INVALID_FACTORY_METHOD_IMPL,
726 decl.name, [decl.name.toString()]);
727 }
728
677 /** 729 /**
678 * Produces a hint if the given identifier is a protected closure, field or 730 * Produces a hint if the given identifier is a protected closure, field or
679 * getter/setter, method closure or invocation accessed outside a subclass. 731 * getter/setter, method closure or invocation accessed outside a subclass.
680 */ 732 */
681 void _checkForInvalidProtectedMemberAccess(SimpleIdentifier identifier) { 733 void _checkForInvalidProtectedMemberAccess(SimpleIdentifier identifier) {
682 if (identifier.inDeclarationContext()) { 734 if (identifier.inDeclarationContext()) {
683 return; 735 return;
684 } 736 }
685 737
686 bool isProtected(Element element) { 738 bool isProtected(Element element) {
(...skipping 10279 matching lines...) Expand 10 before | Expand all | Expand 10 after
10966 return null; 11018 return null;
10967 } 11019 }
10968 if (identical(node.staticElement, variable)) { 11020 if (identical(node.staticElement, variable)) {
10969 if (node.inSetterContext()) { 11021 if (node.inSetterContext()) {
10970 result = true; 11022 result = true;
10971 } 11023 }
10972 } 11024 }
10973 return null; 11025 return null;
10974 } 11026 }
10975 } 11027 }
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