1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Diagnostics;
using Microsoft.VisualStudio.Text.Utilities;
using TextSpan = Microsoft.VisualStudio.Text.Span;
namespace Microsoft.VisualStudio.Text.PatternMatching.Implementation
{
internal partial class PatternMatcher
{
private struct CamelCaseResult
{
public readonly bool FromStart;
public readonly bool Contiguous;
public readonly bool ToEnd;
public readonly int MatchCount;
public readonly ArrayBuilder<TextSpan> MatchedSpansInReverse;
public readonly int ChunkOffset;
public CamelCaseResult(bool fromStart, bool contiguous, bool toEnd, int matchCount, ArrayBuilder<TextSpan> matchedSpansInReverse, int chunkOffset)
{
FromStart = fromStart;
Contiguous = contiguous;
ToEnd = toEnd;
MatchCount = matchCount;
MatchedSpansInReverse = matchedSpansInReverse;
ChunkOffset = chunkOffset;
Debug.Assert(matchedSpansInReverse == null || matchedSpansInReverse.Count == matchCount);
}
public void Free()
{
MatchedSpansInReverse?.Free();
}
public CamelCaseResult WithFromStart(bool fromStart)
=> new CamelCaseResult(fromStart, Contiguous, ToEnd, MatchCount, MatchedSpansInReverse, ChunkOffset);
public CamelCaseResult WithToEnd(bool toEnd)
=> new CamelCaseResult(FromStart, Contiguous, toEnd, MatchCount, MatchedSpansInReverse, ChunkOffset);
public CamelCaseResult WithAddedMatchedSpan(TextSpan value)
{
MatchedSpansInReverse?.Add(value);
return new CamelCaseResult(FromStart, Contiguous, ToEnd, MatchCount + 1, MatchedSpansInReverse, ChunkOffset);
}
}
private static PatternMatchKind GetCamelCaseKind(CamelCaseResult result, StringBreaks candidateHumps)
{
/* CamelCase PatternMatchKind truth table:
* | FromStart | ToEnd | Contiguous || PatternMatchKind |
* | True | True | True || CamelCaseExact |
* | True | True | False || CamelCaseNonContiguousPrefix |
* | True | False | True || CamelCasePrefix |
* | True | False | False || CamelCaseNonContiguousPrefix |
* | False | True | True || CamelCaseSubstring |
* | False | True | False || CamelCaseNonContiguousSubstring |
* | False | False | True || CamelCaseSubstring |
* | False | False | False || CamelCaseNonContiguousSubstring |
*/
if (result.FromStart)
{
if (result.Contiguous)
{
// We contiguously matched humps from the start of this candidate. If we
// matched all the humps, then this was an exact match, otherwise it was a
// contiguous prefix match
return result.ToEnd
? PatternMatchKind.CamelCaseExact
: PatternMatchKind.CamelCasePrefix;
}
else
{
return PatternMatchKind.CamelCaseNonContiguousPrefix;
}
}
else
{
// We didn't match from the start. Distinguish between a match whose humps are all
// contiguous, and one that isn't.
return result.Contiguous
? PatternMatchKind.CamelCaseSubstring
: PatternMatchKind.CamelCaseNonContiguousSubstring;
}
}
}
}
|