@@ -15,7 +15,7 @@ import 'package:analyzer/dart/ast/ast.dart';
1515import 'package:analyzer/dart/ast/token.dart' ;
1616import 'package:analyzer/dart/ast/visitor.dart' ;
1717import 'package:analyzer/dart/element/element.dart'
18- show ClassElement, Element, LibraryElement, LocalElement;
18+ show ClassElement, Element, ExtensionElement, LibraryElement, LocalElement;
1919import 'package:analyzer/dart/element/type.dart' ;
2020import 'package:analyzer/dart/element/type_system.dart' ;
2121import 'package:analyzer/diagnostic/diagnostic.dart' ;
@@ -1211,17 +1211,66 @@ class RelevanceDataCollector extends RecursiveAstVisitor<void> {
12111211 void _recordMemberDepth (DartType targetType, Element element) {
12121212 if (targetType is InterfaceType ) {
12131213 var subclass = targetType.element;
1214+ var extension = element.thisOrAncestorOfType <ExtensionElement >();
1215+ if (extension != null ) {
1216+ // TODO(brianwilkerson) It might be interesting to also know whether the
1217+ // [element] was found in a class, interface, mixin or extension.
1218+ return ;
1219+ }
12141220 var superclass = element.thisOrAncestorOfType <ClassElement >();
12151221 if (superclass != null ) {
1216- var depth = 0 ;
1217- while (subclass != null && subclass != superclass) {
1218- depth++ ;
1219- subclass = subclass.supertype? .element;
1222+ int getSuperclassDepth () {
1223+ var depth = 0 ;
1224+ var currentClass = subclass;
1225+ while (currentClass != null ) {
1226+ if (currentClass == superclass) {
1227+ return depth;
1228+ }
1229+ for (var mixin in currentClass.mixins.reversed) {
1230+ depth++ ;
1231+ if (mixin .element == superclass) {
1232+ return depth;
1233+ }
1234+ }
1235+ depth++ ;
1236+ currentClass = currentClass.supertype? .element;
1237+ }
1238+ return - 1 ;
1239+ }
1240+
1241+ var notFound = 0xFFFF ;
1242+ int getInterfaceDepth (ClassElement currentClass) {
1243+ if (currentClass == null ) {
1244+ return notFound;
1245+ } else if (currentClass == superclass) {
1246+ return 0 ;
1247+ }
1248+ var minDepth = getInterfaceDepth (currentClass.supertype? .element);
1249+ for (var mixin in currentClass.mixins) {
1250+ var depth = getInterfaceDepth (mixin .element);
1251+ if (depth < minDepth) {
1252+ minDepth = depth;
1253+ }
1254+ }
1255+ for (var interface in currentClass.interfaces) {
1256+ var depth = getInterfaceDepth (interface .element);
1257+ if (depth < minDepth) {
1258+ minDepth = depth;
1259+ }
1260+ }
1261+ return minDepth + 1 ;
12201262 }
1221- // TODO(brianwilkerson) Handle the case where the member is defined in
1222- // an interface not on the superclass chain.
1223- if (subclass != null ) {
1224- _recordDistance ('member' , depth);
1263+
1264+ int superclassDepth = getSuperclassDepth ();
1265+ if (superclassDepth >= 0 ) {
1266+ _recordDistance ('member (superclass)' , superclassDepth);
1267+ } else {
1268+ int interfaceDepth = getInterfaceDepth (subclass);
1269+ if (interfaceDepth < notFound) {
1270+ _recordDistance ('member (interface)' , interfaceDepth);
1271+ } else {
1272+ _recordDistance ('member (not found)' , 0 );
1273+ }
12251274 }
12261275 }
12271276 }
0 commit comments