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

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

Issue 2531333006: Avoid a crash during summary linking when there are inheritance errors. (Closed)
Patch Set: Created 4 years 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
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/summary/link.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/summary/link.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698