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 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 node.getAncestor((AstNode node) => node is MethodDeclaration); | 693 node.getAncestor((AstNode node) => node is MethodDeclaration); |
694 if (decl == null) { | 694 if (decl == null) { |
695 _errorReporter.reportErrorForNode( | 695 _errorReporter.reportErrorForNode( |
696 HintCode.INVALID_USE_OF_PROTECTED_MEMBER, | 696 HintCode.INVALID_USE_OF_PROTECTED_MEMBER, |
697 node, | 697 node, |
698 [node.methodName.toString(), definingClass.name]); | 698 [node.methodName.toString(), definingClass.name]); |
699 return; | 699 return; |
700 } | 700 } |
701 | 701 |
702 ClassElement invokingClass = decl.element?.enclosingElement; | 702 ClassElement invokingClass = decl.element?.enclosingElement; |
703 if (!_hasSuperType(invokingClass, definingClass.type)) { | 703 if (!_hasTypeOrSuperType(invokingClass, definingClass.type)) { |
704 _errorReporter.reportErrorForNode( | 704 _errorReporter.reportErrorForNode( |
705 HintCode.INVALID_USE_OF_PROTECTED_MEMBER, | 705 HintCode.INVALID_USE_OF_PROTECTED_MEMBER, |
706 node, | 706 node, |
707 [node.methodName.toString(), definingClass.name]); | 707 [node.methodName.toString(), definingClass.name]); |
708 } | 708 } |
709 } | 709 } |
710 | 710 |
711 /** | 711 /** |
712 * Produces a hint if the given identifier is a protected field or getter | 712 * Produces a hint if the given identifier is a protected field or getter |
713 * accessed outside a subclass. | 713 * accessed outside a subclass. |
714 */ | 714 */ |
715 void _checkForInvalidProtectedPropertyAccess(SimpleIdentifier identifier) { | 715 void _checkForInvalidProtectedPropertyAccess(SimpleIdentifier identifier) { |
716 if (identifier.inDeclarationContext()) { | 716 if (identifier.inDeclarationContext()) { |
717 return; | 717 return; |
718 } | 718 } |
719 Element element = identifier.bestElement; | 719 Element element = identifier.bestElement; |
720 if (element is PropertyAccessorElement && | 720 if (element is PropertyAccessorElement && |
721 element.enclosingElement is ClassElement && | 721 element.enclosingElement is ClassElement && |
722 (element.isProtected || element.variable.isProtected)) { | 722 (element.isProtected || element.variable.isProtected)) { |
723 ClassElement definingClass = element.enclosingElement; | 723 ClassElement definingClass = element.enclosingElement; |
724 ClassDeclaration accessingClass = | 724 ClassDeclaration accessingClass = |
725 identifier.getAncestor((AstNode node) => node is ClassDeclaration); | 725 identifier.getAncestor((AstNode node) => node is ClassDeclaration); |
726 | 726 |
727 if (accessingClass == null) { | 727 if (accessingClass == null) { |
728 _errorReporter.reportErrorForNode( | 728 _errorReporter.reportErrorForNode( |
729 HintCode.INVALID_USE_OF_PROTECTED_MEMBER, | 729 HintCode.INVALID_USE_OF_PROTECTED_MEMBER, |
730 identifier, | 730 identifier, |
731 [identifier.name.toString(), definingClass.name]); | 731 [identifier.name.toString(), definingClass.name]); |
732 } else if (!_hasSuperType(accessingClass.element, definingClass.type)) { | 732 } else if (!_hasTypeOrSuperType( |
| 733 accessingClass.element, definingClass.type)) { |
733 _errorReporter.reportErrorForNode( | 734 _errorReporter.reportErrorForNode( |
734 HintCode.INVALID_USE_OF_PROTECTED_MEMBER, | 735 HintCode.INVALID_USE_OF_PROTECTED_MEMBER, |
735 identifier, | 736 identifier, |
736 [identifier.name.toString(), definingClass.name]); | 737 [identifier.name.toString(), definingClass.name]); |
737 } | 738 } |
738 } | 739 } |
739 } | 740 } |
740 | 741 |
741 /** | 742 /** |
742 * Check that the imported library does not define a loadLibrary function. The
import has already | 743 * Check that the imported library does not define a loadLibrary function. The
import has already |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
999 // _errorReporter.reportErrorForNode( | 1000 // _errorReporter.reportErrorForNode( |
1000 // HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE, | 1001 // HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE, |
1001 // node.name, | 1002 // node.name, |
1002 // [classElement.displayName]); | 1003 // [classElement.displayName]); |
1003 // return true; | 1004 // return true; |
1004 // } | 1005 // } |
1005 // } | 1006 // } |
1006 // return false; | 1007 // return false; |
1007 // } | 1008 // } |
1008 | 1009 |
1009 bool _hasSuperClassOrMixin(ClassElement element, InterfaceType type) { | 1010 bool _hasTypeOrSuperType(ClassElement element, InterfaceType type) => |
1010 List<ClassElement> seenClasses = <ClassElement>[]; | 1011 element != null && |
1011 while (element != null && !seenClasses.contains(element)) { | 1012 (element.type == type || element.allSupertypes.contains(type)); |
1012 if (element.type == type) { | |
1013 return true; | |
1014 } | |
1015 | |
1016 if (element.mixins.any((InterfaceType t) => t == type)) { | |
1017 return true; | |
1018 } | |
1019 | |
1020 seenClasses.add(element); | |
1021 element = element.supertype?.element; | |
1022 } | |
1023 | |
1024 return false; | |
1025 } | |
1026 | |
1027 bool _hasSuperType(ClassElement element, InterfaceType type) => | |
1028 element != null && element.allSupertypes.contains(type); | |
1029 | 1013 |
1030 /** | 1014 /** |
1031 * Given a parenthesized expression, this returns the parent (or recursively g
rand-parent) of the | 1015 * Given a parenthesized expression, this returns the parent (or recursively g
rand-parent) of the |
1032 * expression that is a parenthesized expression, but whose parent is not a pa
renthesized | 1016 * expression that is a parenthesized expression, but whose parent is not a pa
renthesized |
1033 * expression. | 1017 * expression. |
1034 * | 1018 * |
1035 * For example given the code `(((e)))`: `(e) -> (((e)))`. | 1019 * For example given the code `(((e)))`: `(e) -> (((e)))`. |
1036 * | 1020 * |
1037 * @param parenthesizedExpression some expression whose parent is a parenthesi
zed expression | 1021 * @param parenthesizedExpression some expression whose parent is a parenthesi
zed expression |
1038 * @return the first parent or grand-parent that is a parenthesized expression
, that does not have | 1022 * @return the first parent or grand-parent that is a parenthesized expression
, that does not have |
(...skipping 9931 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10970 return null; | 10954 return null; |
10971 } | 10955 } |
10972 if (identical(node.staticElement, variable)) { | 10956 if (identical(node.staticElement, variable)) { |
10973 if (node.inSetterContext()) { | 10957 if (node.inSetterContext()) { |
10974 result = true; | 10958 result = true; |
10975 } | 10959 } |
10976 } | 10960 } |
10977 return null; | 10961 return null; |
10978 } | 10962 } |
10979 } | 10963 } |
OLD | NEW |