Skip to content

Commit e636152

Browse files
authored
Fixing license match post-filtering calculation with traling contained range. (#1489)
1 parent 76c5443 commit e636152

File tree

5 files changed

+37
-20
lines changed

5 files changed

+37
-20
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
- Fixed small ambiguity in the order of license match evaluation.
44
- Resolve `analysis_options.yaml` dev dependency to expose transitive formatter options.
55
- Fixed license coverage calculation.
6+
- Fixed license match post-filtering.
67

78
## 0.22.23
89

lib/src/license_detection/license_detector.dart

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -268,25 +268,33 @@ double calculateUnclaimedTokenPercentage(
268268
/// Returns the number of tokens in the longest unclaimed token
269269
/// sequence.
270270
int findLongestUnclaimedTokenRange(List<LicenseMatch> matches, int end) {
271-
var ranges = <Range>[];
272271
if (matches.isEmpty) return end;
273272

274-
for (var match in matches) {
275-
ranges.add(Range(match.tokenRange.start, match.tokenRange.end));
276-
}
277-
278-
ranges.sort(sortRangeOnStartValue);
279-
var maxTokenSequence = ranges.first.start - 0;
273+
var maxUnclaimed = 0;
274+
275+
// create an end-of-range marker at the end of ranges for easier computation
276+
final ranges = [...matches.map((m) => m.tokenRange), Range(end, end)];
277+
278+
// move position from the start up to the end, checking uncovered ranges
279+
for (var pos = 0; pos < end;) {
280+
// check if inside a range
281+
final skipToEnd = ranges
282+
.where((r) => r.containsIndex(pos))
283+
.map((r) => r.end)
284+
.fold(-1, max);
285+
if (skipToEnd > -1) {
286+
assert(pos < skipToEnd);
287+
pos = skipToEnd;
288+
continue;
289+
}
280290

281-
for (var i = 1; i < ranges.length; i++) {
282-
maxTokenSequence = max(
283-
ranges[i].start - ranges[i - 1].end,
284-
maxTokenSequence,
285-
);
291+
// jump to next range
292+
final nextRange = ranges
293+
.where((r) => r.start > pos)
294+
.reduce((a, b) => a.start.compareTo(b.start) <= 0 ? a : b);
295+
maxUnclaimed = max(maxUnclaimed, nextRange.start - pos);
296+
pos = nextRange.end;
286297
}
287298

288-
maxTokenSequence = max(maxTokenSequence, end - ranges.last.end);
289-
return maxTokenSequence;
299+
return maxUnclaimed;
290300
}
291-
292-
int sortRangeOnStartValue(Range a, Range b) => a.start - b.start;

lib/src/license_detection/token_matcher.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ class Range {
5454
(end >= other.start && end <= other.end);
5555
}
5656

57+
bool containsIndex(int value) => start <= value && value < end;
58+
5759
@override
5860
String toString() => 'Range($start-$end)';
5961
}

test/license_detector_test.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,16 @@ void main() {
258258
160,
259259
1000,
260260
);
261+
262+
_testLongestUnclaimedTokenRange(
263+
'Trailing contained range',
264+
[
265+
_dummyLicenseMatchInstance(0.9, '', start: 30, end: 940),
266+
_dummyLicenseMatchInstance(0.9, '', start: 50, end: 70),
267+
],
268+
60,
269+
1000,
270+
);
261271
});
262272
}
263273

test/licenses/license_coverage_test.dart

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ void main() {
1616
license.content,
1717
relativePath: 'LICENSE',
1818
);
19-
// TODO: fix detection and return at least one match (https://github.com/dart-lang/pana/issues/1484)
20-
if (license.identifier == 'SSH-OpenSSH') {
21-
continue;
22-
}
2319
final match = detected
2420
.where((l) => l.spdxIdentifier == license.identifier)
2521
.single;

0 commit comments

Comments
 (0)