-
Notifications
You must be signed in to change notification settings - Fork 237
Added Handler for Semantic Tokenization #1328
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
TylerLeonhardt
merged 64 commits into
PowerShell:master
from
justinytchen:semantic-token
Jul 30, 2020
Merged
Changes from 28 commits
Commits
Show all changes
64 commits
Select commit
Hold shift + click to select a range
2790655
added basic semantic token support
04458e4
removed unnecessary imports
2e46016
removed unnecessary field
b3077cc
minor refactoring changes
f68e4e3
minor refactoring changes
6f28dc5
change tokenize to non async
d960ac7
rename handler
2853580
refactoring + copyright
a55108c
renamed handler file
75b6386
Delete log20200713.txt
justinytchen 01bde39
moved/refactored handler
ea0fab2
added e2e tets
ccf1028
Merge branch 'semantic-token' of https://github.com/justinytchen/Powe…
170fb6b
updated test
4764d2e
remove pragma
5572a16
removed extra spacing
f8411cc
added testing for converting from PS token to semantic tokens
4b7db57
refactored the functions related to converting between tokens
a20241b
refactored ConvertSemanticToken
bebc507
fixed tests
5550780
added more test cases
3fb9abe
fixed spacing
73bda8d
added enum test
4703804
fixed spacing issues
c013b1d
fixed spacing, added note about token array representation
5ab13c4
changed name to PsesSemanticTokensHandler
62566a8
reformatted fields
bafff92
renamed file
5a631dd
used Assert.Collection instead of Assert.Single
7df4e67
modified yml file to fix build
b2e43b1
undo changes in yml file
4a6955f
addressed issues in PR
f4562c0
added basic semantic token support
6264c0b
removed unnecessary imports
ae5a498
removed unnecessary field
9ae83aa
minor refactoring changes
b4d558c
minor refactoring changes
874db6e
change tokenize to non async
bec8bd6
rename handler
9848c71
refactoring + copyright
855790c
renamed handler file
514012c
moved/refactored handler
5294cf4
added e2e tets
9aed66b
Delete log20200713.txt
justinytchen b4024e7
updated test
4908752
remove pragma
2e4f098
removed extra spacing
8f5db93
added testing for converting from PS token to semantic tokens
42714b5
refactored the functions related to converting between tokens
1657fdf
refactored ConvertSemanticToken
ebae357
fixed tests
f109d71
added more test cases
c9b858d
fixed spacing
d8f0a36
added enum test
3fba85f
fixed spacing issues
8592540
fixed spacing, added note about token array representation
d4a86ac
changed name to PsesSemanticTokensHandler
e86c5b8
reformatted fields
6c21195
renamed file
09d632c
used Assert.Collection instead of Assert.Single
7c4b3b7
addressed issues in PR
99c1c0b
Merge branch 'semantic-token' of https://github.com/justinytchen/Powe…
725e8eb
remove unused using
1aedd88
Delete Untitled-1.json
justinytchen File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
165 changes: 165 additions & 0 deletions
165
src/PowerShellEditorServices/Services/TextDocument/Handlers/PsesSemanticTokensHandler.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
// | ||
// Copyright (c) Microsoft. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
// | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Management.Automation.Language; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Microsoft.Extensions.Logging; | ||
using Microsoft.PowerShell.EditorServices.Services; | ||
using Microsoft.PowerShell.EditorServices.Services.TextDocument; | ||
using Microsoft.PowerShell.EditorServices.Utility; | ||
using OmniSharp.Extensions.LanguageServer.Protocol; | ||
using OmniSharp.Extensions.LanguageServer.Protocol.Document.Proposals; | ||
using OmniSharp.Extensions.LanguageServer.Protocol.Models; | ||
using OmniSharp.Extensions.LanguageServer.Protocol.Models.Proposals; | ||
|
||
namespace Microsoft.PowerShell.EditorServices.Handlers | ||
{ | ||
internal class PsesSemanticTokensHandler : SemanticTokensHandler | ||
{ | ||
private static readonly SemanticTokensRegistrationOptions s_registrationOptions = new SemanticTokensRegistrationOptions | ||
{ | ||
DocumentSelector = LspUtils.PowerShellDocumentSelector, | ||
Legend = new SemanticTokensLegend(), | ||
DocumentProvider = new Supports<SemanticTokensDocumentProviderOptions>( | ||
isSupported: true, | ||
new SemanticTokensDocumentProviderOptions | ||
{ | ||
Edits = true | ||
}), | ||
RangeProvider = true | ||
}; | ||
private readonly ILogger _logger; | ||
private readonly WorkspaceService _workspaceService; | ||
|
||
public PsesSemanticTokensHandler(ILogger<PsesSemanticTokensHandler> logger, WorkspaceService workspaceService) : base(s_registrationOptions) | ||
TylerLeonhardt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
_logger = logger; | ||
_workspaceService = workspaceService; | ||
} | ||
|
||
protected override Task Tokenize(SemanticTokensBuilder builder, ITextDocumentIdentifierParams identifier, | ||
CancellationToken cancellationToken) | ||
{ | ||
ScriptFile file = _workspaceService.GetFile(DocumentUri.GetFileSystemPath(identifier)); | ||
TylerLeonhardt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
foreach (Token token in file.ScriptTokens) | ||
{ | ||
PushToken(token, builder); | ||
} | ||
return Task.CompletedTask; | ||
} | ||
|
||
private static void PushToken(Token token, SemanticTokensBuilder builder) | ||
{ | ||
foreach (SemanticToken sToken in ConvertToSemanticTokens(token)) | ||
{ | ||
builder.Push( | ||
sToken.Line, | ||
sToken.Index, | ||
length: sToken.Text.Length, | ||
sToken.Type, | ||
tokenModifiers: sToken.TokenModifiers); | ||
} | ||
} | ||
|
||
internal static IEnumerable<SemanticToken> ConvertToSemanticTokens(Token token) | ||
{ | ||
if (token is StringExpandableToken stringExpandableToken) | ||
{ | ||
// Try parsing tokens within the string | ||
if (stringExpandableToken.NestedTokens != null) | ||
{ | ||
foreach (Token t in stringExpandableToken.NestedTokens) | ||
{ | ||
foreach (SemanticToken subToken in ConvertToSemanticTokens(t)) | ||
yield return subToken; | ||
} | ||
yield break; | ||
} | ||
} | ||
|
||
SemanticTokenType mappedType = MapSemanticTokenType(token); | ||
if (mappedType == null) | ||
{ | ||
yield break; | ||
} | ||
|
||
//Tokens line and col numbers indexed starting from 1, expecting indexing from 0 | ||
int line = token.Extent.StartLineNumber - 1; | ||
int index = token.Extent.StartColumnNumber - 1; | ||
SemanticToken sToken = new SemanticToken(token.Text, mappedType, | ||
line, index, Array.Empty<string>()); | ||
yield return sToken; | ||
TylerLeonhardt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
private static SemanticTokenType MapSemanticTokenType(Token token) | ||
{ | ||
// First check token flags | ||
if ((token.TokenFlags & TokenFlags.Keyword) != 0) | ||
{ | ||
return SemanticTokenType.Keyword; | ||
} | ||
|
||
if ((token.TokenFlags & TokenFlags.CommandName) != 0) | ||
{ | ||
return SemanticTokenType.Function; | ||
} | ||
|
||
if (token.Kind != TokenKind.Generic && (token.TokenFlags & | ||
(TokenFlags.BinaryOperator | TokenFlags.UnaryOperator | TokenFlags.AssignmentOperator)) != 0) | ||
{ | ||
return SemanticTokenType.Operator; | ||
} | ||
|
||
if ((token.TokenFlags & TokenFlags.TypeName) != 0) | ||
{ | ||
return SemanticTokenType.Type; | ||
} | ||
|
||
if ((token.TokenFlags & TokenFlags.MemberName) != 0) | ||
{ | ||
return SemanticTokenType.Member; | ||
} | ||
|
||
// Only check token kind after checking flags | ||
switch (token.Kind) | ||
{ | ||
case TokenKind.Comment: | ||
return SemanticTokenType.Comment; | ||
|
||
case TokenKind.Parameter: | ||
case TokenKind.Generic when token is StringLiteralToken slt && slt.Text.StartsWith("--"): | ||
return SemanticTokenType.Parameter; | ||
|
||
case TokenKind.Variable: | ||
case TokenKind.SplattedVariable: | ||
return SemanticTokenType.Variable; | ||
|
||
case TokenKind.StringExpandable: | ||
case TokenKind.StringLiteral: | ||
case TokenKind.HereStringExpandable: | ||
case TokenKind.HereStringLiteral: | ||
return SemanticTokenType.String; | ||
|
||
case TokenKind.Number: | ||
return SemanticTokenType.Number; | ||
|
||
case TokenKind.Generic: | ||
return SemanticTokenType.Function; | ||
} | ||
|
||
return null; | ||
} | ||
|
||
protected override Task<SemanticTokensDocument> GetSemanticTokensDocument( | ||
ITextDocumentIdentifierParams @params, | ||
CancellationToken cancellationToken) | ||
{ | ||
return Task.FromResult(new SemanticTokensDocument(GetRegistrationOptions().Legend)); | ||
} | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
src/PowerShellEditorServices/Services/TextDocument/SemanticToken.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
using System.Collections.Generic; | ||
using OmniSharp.Extensions.LanguageServer.Protocol.Models.Proposals; | ||
|
||
namespace Microsoft.PowerShell.EditorServices.Services.TextDocument | ||
{ | ||
internal class SemanticToken | ||
{ | ||
public SemanticToken(string text, SemanticTokenType type, int line, int index, IEnumerable<string> tokenModifiers) | ||
TylerLeonhardt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
Line = line; | ||
Text = text; | ||
Index = index; | ||
Type = type; | ||
TokenModifiers = tokenModifiers; | ||
} | ||
|
||
public string Text {get; set;} | ||
|
||
public int Line {get; set;} | ||
|
||
public int Index {get; set;} | ||
|
||
public SemanticTokenType Type {get; set;} | ||
|
||
public IEnumerable<string> TokenModifiers {get; set;} | ||
TylerLeonhardt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.