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

Side by Side Diff: pkg/analyzer/lib/src/task/strong/checker.dart

Issue 2986063002: Avoid issuing incorrect errors when super mixins are enabled (Closed)
Patch Set: Address comments Created 3 years, 4 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
« no previous file with comments | « no previous file | pkg/analyzer/test/src/task/strong/checker_test.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) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be 5 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be
6 // refactored to fit into analyzer. 6 // refactored to fit into analyzer.
7 library analyzer.src.task.strong.checker; 7 library analyzer.src.task.strong.checker;
8 8
9 import 'dart:collection'; 9 import 'dart:collection';
10 import 'package:analyzer/analyzer.dart'; 10 import 'package:analyzer/analyzer.dart';
(...skipping 1619 matching lines...) Expand 10 before | Expand all | Expand 10 after
1630 var interfaces = _collectInterfacesToCheck(element.type); 1630 var interfaces = _collectInterfacesToCheck(element.type);
1631 var visitedClasses = new Set<InterfaceType>(); 1631 var visitedClasses = new Set<InterfaceType>();
1632 var visitedMembers = new HashSet<String>(); 1632 var visitedMembers = new HashSet<String>();
1633 1633
1634 // Checks all most-derived concrete members on this `type`. We skip over 1634 // Checks all most-derived concrete members on this `type`. We skip over
1635 // members that are already `visitedMembers`, because they were overridden 1635 // members that are already `visitedMembers`, because they were overridden
1636 // and we've already checked that member. 1636 // and we've already checked that member.
1637 // 1637 //
1638 // Because of that, it is important we visit types in the order that they 1638 // Because of that, it is important we visit types in the order that they
1639 // will override members. 1639 // will override members.
1640 void checkType(InterfaceType type, AstNode location) { 1640 // If checkingMixin is true, then we are checking [type] in a mixin position
1641 // and hence should consider its own mixins and superclass as abstract.
1642 void checkType(InterfaceType type, AstNode location,
1643 {bool checkingMixin: false}) {
1641 // Skip `Object` because we don't need to check those members here. 1644 // Skip `Object` because we don't need to check those members here.
1642 // (because `Object` is the root of everything, it will be checked in 1645 // (because `Object` is the root of everything, it will be checked in
1643 // _checkSuperOverrides for all classes). 1646 // _checkSuperOverrides for all classes).
1644 if (type == null || type.isObject || !visitedClasses.add(type)) return; 1647 if (type == null || type.isObject || !visitedClasses.add(type)) return;
1645 1648
1646 // Check `member` against all `interfaces`. 1649 // Check `member` against all `interfaces`.
1647 void checkOverride(ExecutableElement member, [AstNode loc]) { 1650 void checkOverride(ExecutableElement member, [AstNode loc]) {
1648 if (!visitedMembers.add(member.name)) return; 1651 if (!visitedMembers.add(member.name)) return;
1649 for (var interface in interfaces) { 1652 for (var interface in interfaces) {
1650 if (_checkMemberOverride(member, interface, loc ?? location) == 1653 if (_checkMemberOverride(member, interface, loc ?? location) ==
(...skipping 11 matching lines...) Expand all
1662 // Otherwise, we'll use the `extends` or `with` clause. 1665 // Otherwise, we'll use the `extends` or `with` clause.
1663 var isRootClass = identical(location, node); 1666 var isRootClass = identical(location, node);
1664 1667
1665 // Check direct overrides on the class. 1668 // Check direct overrides on the class.
1666 if (isRootClass) { 1669 if (isRootClass) {
1667 _checkClassMembers(node, checkOverride); 1670 _checkClassMembers(node, checkOverride);
1668 } else { 1671 } else {
1669 _checkTypeMembers(type, checkOverride); 1672 _checkTypeMembers(type, checkOverride);
1670 } 1673 }
1671 1674
1672 // Check mixin members against interfaces. 1675 // If we are currently checking a mixin, then its own mixins and
1673 // 1676 // superclass are abstract, and we should not check their members.
1674 // We visit mixins in reverse order to reflect how they override 1677 // This should only happen when super mixins is enabled, and we
1675 // eachother. 1678 // don't do proper checking for super mixins (we don't check that
1676 for (int i = type.mixins.length - 1; i >= 0; i--) { 1679 // the contract implied by the mixin declaration is satisfied by
1677 checkType(type.mixins[i], 1680 // the mixin use), but this prevents us from erroneously
1678 isRootClass ? _withClause(node).mixinTypes[i] : location); 1681 // rejecting some super mixin patterns.
1682 // If this is a mixin application (class A = Object with B)
1683 // however, then we do still need to treat the mixin as concrete.
1684 if (!checkingMixin || type.element.isMixinApplication) {
1685 // Check mixin members against interfaces.
1686 //
1687 // We visit mixins in reverse order to reflect how they override
1688 // eachother.
1689 for (int i = type.mixins.length - 1; i >= 0; i--) {
1690 checkType(type.mixins[i],
1691 isRootClass ? _withClause(node).mixinTypes[i] : location,
1692 checkingMixin: true);
1693 }
1694
1695 // Check members on the superclass.
1696 checkType(type.superclass,
1697 isRootClass ? _extendsErrorLocation(node) : location,
1698 checkingMixin: checkingMixin);
1679 } 1699 }
1680
1681 // Check members on the superclass.
1682 checkType(type.superclass,
1683 isRootClass ? _extendsErrorLocation(node) : location);
1684 } 1700 }
1685 1701
1686 checkType(element.type, node); 1702 checkType(element.type, node);
1687 } 1703 }
1688 1704
1689 /// Gets the set of all interfaces on [type] that should be checked to see 1705 /// Gets the set of all interfaces on [type] that should be checked to see
1690 /// if type's members are overriding them correctly. 1706 /// if type's members are overriding them correctly.
1691 /// 1707 ///
1692 /// In particular, we need to check these overrides for the definitions in 1708 /// In particular, we need to check these overrides for the definitions in
1693 /// the class itself and each its superclasses (and mixins). 1709 /// the class itself and each its superclasses (and mixins).
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
1958 } 1974 }
1959 1975
1960 /// If node is a [ClassDeclaration] returns its members, otherwise if node is 1976 /// If node is a [ClassDeclaration] returns its members, otherwise if node is
1961 /// a [ClassTypeAlias] this returns an empty list. 1977 /// a [ClassTypeAlias] this returns an empty list.
1962 WithClause _withClause(Declaration node) { 1978 WithClause _withClause(Declaration node) {
1963 return node is ClassDeclaration 1979 return node is ClassDeclaration
1964 ? node.withClause 1980 ? node.withClause
1965 : (node as ClassTypeAlias).withClause; 1981 : (node as ClassTypeAlias).withClause;
1966 } 1982 }
1967 } 1983 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/src/task/strong/checker_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698