Skip to content

Commit a1c1401

Browse files
author
Mikhail Arkhipov
committed
Hightlight of unknown items
1 parent 1e8291b commit a1c1401

File tree

1 file changed

+31
-8
lines changed

1 file changed

+31
-8
lines changed

src/LanguageServer/Impl/Sources/DocumentHighlightSource.cs

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,17 @@
1414
// permissions and limitations under the License.
1515

1616
using System;
17-
using System.Collections.Generic;
1817
using System.IO;
1918
using System.Linq;
2019
using System.Threading;
2120
using System.Threading.Tasks;
2221
using Microsoft.Python.Analysis;
23-
using Microsoft.Python.Analysis.Documents;
24-
using Microsoft.Python.Analysis.Modules;
25-
using Microsoft.Python.Analysis.Types;
2622
using Microsoft.Python.Core;
27-
using Microsoft.Python.Core.IO;
2823
using Microsoft.Python.Core.Text;
2924
using Microsoft.Python.LanguageServer.Documents;
3025
using Microsoft.Python.LanguageServer.Protocol;
26+
using Microsoft.Python.Parsing;
27+
using Microsoft.Python.Parsing.Ast;
3128

3229
namespace Microsoft.Python.LanguageServer.Sources {
3330
internal sealed class DocumentHighlightSource {
@@ -40,25 +37,51 @@ public DocumentHighlightSource(IServiceContainer services) {
4037

4138
public async Task<DocumentHighlight[]> DocumentHighlightAsync(Uri uri, SourceLocation location, CancellationToken cancellationToken = default) {
4239
if (uri == null) {
43-
return Array.Empty<DocumentHighlight>();
40+
return null;
4441
}
4542

4643
var analysis = await Document.GetAnalysisAsync(uri, _services, DocumentHighlightAnalysisTimeout, cancellationToken);
4744
var definitionSource = new DefinitionSource(_services);
4845

4946
var definition = definitionSource.FindDefinition(analysis, location, out var definingMember);
5047
if (definition == null || definingMember == null) {
51-
return Array.Empty<DocumentHighlight>();
48+
return FromTokens(analysis, location);
5249
}
5350

5451
var rootDefinition = definingMember.GetRootDefinition();
5552

5653
var result = rootDefinition.References
5754
.Where(r => r.DocumentUri.Equals(uri))
58-
.Select((r, i) => new DocumentHighlight { kind = (i == 0) ? DocumentHighlightKind.Write : DocumentHighlightKind.Read, range = r.Span })
55+
.Select((r, i) => new DocumentHighlight {
56+
kind = i == 0 ? DocumentHighlightKind.Write : DocumentHighlightKind.Read, range = r.Span
57+
})
5958
.ToArray();
6059

6160
return result;
6261
}
62+
63+
private static DocumentHighlight[] FromTokens(IDocumentAnalysis analysis, SourceLocation location) {
64+
var position = analysis.Ast.LocationToIndex(location);
65+
var content = analysis.Document.Content;
66+
67+
var tokenizer = new Tokenizer(analysis.Document.Interpreter.LanguageVersion);
68+
tokenizer.Initialize(null, new StringReader(content), SourceLocation.MinValue);
69+
var tokens = tokenizer.ReadTokens(content.Length);
70+
71+
var t = tokens.FirstOrDefault(x => x.SourceSpan.Start.Index <= position && position < x.SourceSpan.End.Index);
72+
if (t.Category != TokenCategory.None) {
73+
var length = t.SourceSpan.End.Index - t.SourceSpan.Start.Index;
74+
return tokens
75+
.Where(x =>
76+
x.SourceSpan.End.Index - x.SourceSpan.Start.Index == length &&
77+
string.Compare(content, x.SourceSpan.Start.Index, content, t.SourceSpan.Start.Index, length) == 0)
78+
.Select(s => new DocumentHighlight {
79+
kind = DocumentHighlightKind.Text,
80+
range = s.SourceSpan
81+
}).ToArray();
82+
}
83+
84+
return null;
85+
}
6386
}
6487
}

0 commit comments

Comments
 (0)