@@ -21,26 +21,59 @@ class Scope {
21
21
}
22
22
23
23
Scope ? findScope ({required int offset, int length = 0 }) {
24
- if ( (this .offset <= offset &&
24
+ var scopeContainsOffset = (this .offset <= offset &&
25
25
this .offset + this .length > offset + length) ||
26
- (this .offset == offset && this .length == length)) {
26
+ (this .offset == offset && this .length == length);
27
+
28
+ if (scopeContainsOffset) {
27
29
return findInScope (offset: offset, length: length);
28
30
}
31
+
29
32
return null ;
30
33
}
31
34
35
+ /// Assumes a sorted [list] , where [matcher] would return false
36
+ /// for all elements before it returns true. This lets us do a bisect
37
+ /// to quickly find the first element, as opposed to a linear firstWhere.
38
+ int _first <T >(List <T > list, bool Function (T item) matcher) {
39
+ if (list.isEmpty) {
40
+ return 0 ;
41
+ }
42
+
43
+ var low = 0 ;
44
+ var high = list.length;
45
+
46
+ while (low < high) {
47
+ var half = ((low + high) / 2 ).floor ();
48
+ if (matcher (list[half])) {
49
+ high = half;
50
+ } else {
51
+ low = half + 1 ;
52
+ }
53
+ }
54
+
55
+ return low;
56
+ }
57
+
32
58
Scope findInScope ({required int offset, int length = 0 }) {
33
- var scopeAtOffset = children. firstWhere (
34
- (scope) =>
35
- scope.offset <= offset &&
36
- scope.offset + scope.length >= offset + length ,
37
- orElse : () => this );
59
+ var end = offset + length;
60
+ var scopeIndex = _first (
61
+ children,
62
+ (scope) => scope.offset > end ,
63
+ );
38
64
39
- if (scopeAtOffset == this ) {
65
+ if (scopeIndex == 0 ) {
40
66
return this ;
41
67
}
42
68
43
- return scopeAtOffset.findInScope (offset: offset, length: length);
69
+ var candidate = children.elementAt (scopeIndex - 1 );
70
+ var containsOffset = candidate.offset <= offset &&
71
+ candidate.offset + candidate.length >= offset + length;
72
+ if (containsOffset) {
73
+ return candidate.findInScope (offset: offset, length: length);
74
+ }
75
+
76
+ return this ;
44
77
}
45
78
46
79
void addSymbol (StylesheetDocumentSymbol symbol) {
0 commit comments