Skip to content

Commit bf5171c

Browse files
bwilkersoncommit-bot@chromium.org
authored andcommitted
Add support for reporting how an accessed member related to the context type and extract feature computation
Change-Id: Id5cd64ac5aaa8b5f502f978e4dab5f9502efb47c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/138560 Reviewed-by: Jaime Wren <[email protected]> Commit-Queue: Brian Wilkerson <[email protected]>
1 parent 8d26e3d commit bf5171c

File tree

2 files changed

+542
-51
lines changed

2 files changed

+542
-51
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
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.
4+
5+
/// Utility methods to compute the value of the features used for code
6+
/// completion.
7+
import 'package:analyzer/dart/element/element.dart' show ClassElement;
8+
9+
// TODO(brianwilkerson) Move this file to `lib` so that it can be used by the
10+
// completion contributors.
11+
12+
/// Return the inheritance distance between the [subclass] and the [superclass].
13+
/// We define the inheritance distance between two types to be zero if the two
14+
/// types are the same and the minimum number of edges that must be traversed in
15+
/// the type graph to get from the subtype to the supertype if the two types are
16+
/// not the same. Return `-1` if the [subclass] is not a subclass of the
17+
/// [superclass].
18+
int inheritanceDistance(ClassElement subclass, ClassElement superclass) {
19+
return _inheritanceDistance(subclass, superclass, {});
20+
}
21+
22+
/// Return the value of the inheritance distance feature for a member defined in
23+
/// the [superclass] that is being accessed through an expression whose static
24+
/// type is the [subclass].
25+
double inheritanceDistanceFeature(
26+
ClassElement subclass, ClassElement superclass) {
27+
var distance = _inheritanceDistance(subclass, superclass, {});
28+
if (distance < 0) {
29+
return 0;
30+
}
31+
return 1 / (distance + 1);
32+
}
33+
34+
/// Return the inheritance distance between the [subclass] and the [superclass].
35+
/// The set of [visited] elements is used to guard against cycles in the type
36+
/// graph.
37+
///
38+
/// This is the implementation of [inheritanceDistance].
39+
int _inheritanceDistance(
40+
ClassElement subclass, ClassElement superclass, Set<ClassElement> visited) {
41+
if (subclass == null) {
42+
return -1;
43+
} else if (subclass == superclass) {
44+
return 0;
45+
} else if (!visited.add(subclass)) {
46+
return -1;
47+
}
48+
var minDepth =
49+
_inheritanceDistance(subclass.supertype?.element, superclass, visited);
50+
for (var mixin in subclass.mixins) {
51+
var depth = _inheritanceDistance(mixin.element, superclass, visited);
52+
if (minDepth < 0 || depth < minDepth) {
53+
minDepth = depth;
54+
}
55+
}
56+
for (var interface in subclass.interfaces) {
57+
var depth = _inheritanceDistance(interface.element, superclass, visited);
58+
if (minDepth < 0 || (depth >= 0 && depth < minDepth)) {
59+
minDepth = depth;
60+
}
61+
}
62+
visited.remove(subclass);
63+
if (minDepth < 0) {
64+
return minDepth;
65+
}
66+
return minDepth + 1;
67+
}

0 commit comments

Comments
 (0)