Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 import 'dart:collection'; | 5 import 'dart:collection'; |
| 6 | 6 |
| 7 import 'package:analyzer/dart/ast/ast.dart'; | 7 import 'package:analyzer/dart/ast/ast.dart'; |
| 8 import 'package:analyzer/dart/ast/token.dart'; | 8 import 'package:analyzer/dart/ast/token.dart'; |
| 9 import 'package:analyzer/dart/element/element.dart'; | 9 import 'package:analyzer/dart/element/element.dart'; |
| 10 import 'package:analyzer/dart/element/type.dart'; | 10 import 'package:analyzer/dart/element/type.dart'; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 47 Map<ClassElement, Map<String, ExecutableElement>> _interfaceLookup; | 47 Map<ClassElement, Map<String, ExecutableElement>> _interfaceLookup; |
| 48 | 48 |
| 49 /** | 49 /** |
| 50 * A map between each visited [ClassElement] and the set of [AnalysisError]s f ound on | 50 * A map between each visited [ClassElement] and the set of [AnalysisError]s f ound on |
| 51 * the class element. | 51 * the class element. |
| 52 */ | 52 */ |
| 53 Map<ClassElement, Set<AnalysisError>> _errorsInClassElement = | 53 Map<ClassElement, Set<AnalysisError>> _errorsInClassElement = |
| 54 new HashMap<ClassElement, Set<AnalysisError>>(); | 54 new HashMap<ClassElement, Set<AnalysisError>>(); |
| 55 | 55 |
| 56 /** | 56 /** |
| 57 * Indicates whether errors should be ignored. | |
|
Brian Wilkerson
2016/11/29 19:01:51
Please add an explanation for why we need to not g
Paul Berry
2016/11/29 19:03:45
Done.
| |
| 58 */ | |
| 59 final bool ignoreErrors; | |
| 60 | |
| 61 /** | |
| 57 * Initialize a newly created inheritance manager. | 62 * Initialize a newly created inheritance manager. |
| 58 * | 63 * |
| 59 * @param library the library element context that the inheritance mappings ar e being generated | 64 * @param library the library element context that the inheritance mappings ar e being generated |
| 60 */ | 65 */ |
| 61 InheritanceManager(LibraryElement library, | 66 InheritanceManager(LibraryElement library, |
| 62 {bool includeAbstractFromSuperclasses: false}) { | 67 {bool includeAbstractFromSuperclasses: false, this.ignoreErrors: false}) { |
| 63 this._library = library; | 68 this._library = library; |
| 64 _includeAbstractFromSuperclasses = includeAbstractFromSuperclasses; | 69 _includeAbstractFromSuperclasses = includeAbstractFromSuperclasses; |
| 65 _classLookup = new HashMap<ClassElement, Map<String, ExecutableElement>>(); | 70 _classLookup = new HashMap<ClassElement, Map<String, ExecutableElement>>(); |
| 66 _interfaceLookup = | 71 _interfaceLookup = |
| 67 new HashMap<ClassElement, Map<String, ExecutableElement>>(); | 72 new HashMap<ClassElement, Map<String, ExecutableElement>>(); |
| 68 } | 73 } |
| 69 | 74 |
| 70 /** | 75 /** |
| 71 * Set the new library element context. | 76 * Set the new library element context. |
| 72 * | 77 * |
| (...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 647 * This method is used to report errors on when they are found computing inher itance information. | 652 * This method is used to report errors on when they are found computing inher itance information. |
| 648 * See [ErrorVerifier.checkForInconsistentMethodInheritance] to see where thes e generated | 653 * See [ErrorVerifier.checkForInconsistentMethodInheritance] to see where thes e generated |
| 649 * error codes are reported back into the analysis engine. | 654 * error codes are reported back into the analysis engine. |
| 650 * | 655 * |
| 651 * @param classElt the location of the source for which the exception occurred | 656 * @param classElt the location of the source for which the exception occurred |
| 652 * @param offset the offset of the location of the error | 657 * @param offset the offset of the location of the error |
| 653 * @param length the length of the location of the error | 658 * @param length the length of the location of the error |
| 654 * @param errorCode the error code to be associated with this error | 659 * @param errorCode the error code to be associated with this error |
| 655 * @param arguments the arguments used to build the error message | 660 * @param arguments the arguments used to build the error message |
| 656 */ | 661 */ |
| 657 void _reportError(ClassElement classElt, int offset, int length, | 662 void _reportError( |
| 658 ErrorCode errorCode, List<Object> arguments) { | 663 ClassElement classElt, ErrorCode errorCode, List<Object> arguments) { |
| 664 if (ignoreErrors) { | |
| 665 return; | |
| 666 } | |
| 659 HashSet<AnalysisError> errorSet = _errorsInClassElement[classElt]; | 667 HashSet<AnalysisError> errorSet = _errorsInClassElement[classElt]; |
|
Brian Wilkerson
2016/11/29 19:01:51
We could clean this up to use `putIfAbsent`, if yo
Paul Berry
2016/11/29 19:03:45
Acknowledged.
| |
| 660 if (errorSet == null) { | 668 if (errorSet == null) { |
| 661 errorSet = new HashSet<AnalysisError>(); | 669 errorSet = new HashSet<AnalysisError>(); |
| 662 _errorsInClassElement[classElt] = errorSet; | 670 _errorsInClassElement[classElt] = errorSet; |
| 663 } | 671 } |
| 664 errorSet.add(new AnalysisError( | 672 errorSet.add(new AnalysisError(classElt.source, classElt.nameOffset, |
| 665 classElt.source, offset, length, errorCode, arguments)); | 673 classElt.nameLength, errorCode, arguments)); |
| 666 } | 674 } |
| 667 | 675 |
| 668 /** | 676 /** |
| 669 * Given the set of methods defined by classes above [classElt] in the class h ierarchy, | 677 * Given the set of methods defined by classes above [classElt] in the class h ierarchy, |
| 670 * apply the appropriate inheritance rules to determine those methods inherite d by or overridden | 678 * apply the appropriate inheritance rules to determine those methods inherite d by or overridden |
| 671 * by [classElt]. Also report static warnings | 679 * by [classElt]. Also report static warnings |
| 672 * [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE] and | 680 * [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE] and |
| 673 * [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD] if ap propriate. | 681 * [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD] if ap propriate. |
| 674 * | 682 * |
| 675 * @param classElt the class element to query. | 683 * @param classElt the class element to query. |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 786 // Example: class A inherited only 2 method named 'm'. | 794 // Example: class A inherited only 2 method named 'm'. |
| 787 // One has the function type '() -> int' and one has the function | 795 // One has the function type '() -> int' and one has the function |
| 788 // type '() -> String'. Since neither is a subtype of the other, | 796 // type '() -> String'. Since neither is a subtype of the other, |
| 789 // we create a warning, and have this class inherit nothing. | 797 // we create a warning, and have this class inherit nothing. |
| 790 // | 798 // |
| 791 if (!classHasMember) { | 799 if (!classHasMember) { |
| 792 String firstTwoFuntionTypesStr = | 800 String firstTwoFuntionTypesStr = |
| 793 "${executableElementTypes[0]}, ${executableElementTypes[1]}" ; | 801 "${executableElementTypes[0]}, ${executableElementTypes[1]}" ; |
| 794 _reportError( | 802 _reportError( |
| 795 classElt, | 803 classElt, |
| 796 classElt.nameOffset, | |
| 797 classElt.nameLength, | |
| 798 StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, | 804 StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, |
| 799 [key, firstTwoFuntionTypesStr]); | 805 [key, firstTwoFuntionTypesStr]); |
| 800 } | 806 } |
| 801 } else { | 807 } else { |
| 802 // | 808 // |
| 803 // Example: class A inherits 2 methods named 'm'. | 809 // Example: class A inherits 2 methods named 'm'. |
| 804 // One has the function type '(int) -> dynamic' and one has the | 810 // One has the function type '(int) -> dynamic' and one has the |
| 805 // function type '(num) -> dynamic'. Since they are both a subtype | 811 // function type '(num) -> dynamic'. Since they are both a subtype |
| 806 // of the other, a synthetic function '(dynamic) -> dynamic' is | 812 // of the other, a synthetic function '(dynamic) -> dynamic' is |
| 807 // inherited. | 813 // inherited. |
| 808 // Tests: test_getMapOfMembersInheritedFromInterfaces_ | 814 // Tests: test_getMapOfMembersInheritedFromInterfaces_ |
| 809 // union_multipleSubtypes_* | 815 // union_multipleSubtypes_* |
| 810 // | 816 // |
| 811 List<ExecutableElement> elementArrayToMerge = | 817 List<ExecutableElement> elementArrayToMerge = |
| 812 new List<ExecutableElement>( | 818 new List<ExecutableElement>( |
| 813 subtypesOfAllOtherTypesIndexes.length); | 819 subtypesOfAllOtherTypesIndexes.length); |
| 814 for (int i = 0; i < elementArrayToMerge.length; i++) { | 820 for (int i = 0; i < elementArrayToMerge.length; i++) { |
| 815 elementArrayToMerge[i] = | 821 elementArrayToMerge[i] = |
| 816 elements[subtypesOfAllOtherTypesIndexes[i]]; | 822 elements[subtypesOfAllOtherTypesIndexes[i]]; |
| 817 } | 823 } |
| 818 ExecutableElement mergedExecutableElement = | 824 ExecutableElement mergedExecutableElement = |
| 819 _computeMergedExecutableElement(elementArrayToMerge); | 825 _computeMergedExecutableElement(elementArrayToMerge); |
| 820 resultMap[key] = mergedExecutableElement; | 826 resultMap[key] = mergedExecutableElement; |
| 821 } | 827 } |
| 822 } | 828 } |
| 823 } else { | 829 } else { |
| 824 _reportError( | 830 _reportError( |
| 825 classElt, | 831 classElt, |
| 826 classElt.nameOffset, | |
| 827 classElt.nameLength, | |
| 828 StaticWarningCode | 832 StaticWarningCode |
| 829 .INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, | 833 .INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, |
| 830 [key]); | 834 [key]); |
| 831 } | 835 } |
| 832 } | 836 } |
| 833 }); | 837 }); |
| 834 return resultMap; | 838 return resultMap; |
| 835 } | 839 } |
| 836 | 840 |
| 837 /** | 841 /** |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1241 } | 1245 } |
| 1242 | 1246 |
| 1243 /** | 1247 /** |
| 1244 * Initializes [keys] and [values]. | 1248 * Initializes [keys] and [values]. |
| 1245 */ | 1249 */ |
| 1246 void _initArrays(int initialCapacity) { | 1250 void _initArrays(int initialCapacity) { |
| 1247 _keys = new List<String>(initialCapacity); | 1251 _keys = new List<String>(initialCapacity); |
| 1248 _values = new List<ExecutableElement>(initialCapacity); | 1252 _values = new List<ExecutableElement>(initialCapacity); |
| 1249 } | 1253 } |
| 1250 } | 1254 } |
| OLD | NEW |