|
| 1 | +// Copyright (c) Microsoft Corporation. |
| 2 | +// Licensed under the MIT License. |
| 3 | + |
| 4 | +using System; |
| 5 | +using System.Management.Automation.Language; |
| 6 | +using System.Text.RegularExpressions; |
| 7 | +using Microsoft.PowerShell.EditorServices.Services.TextDocument; |
| 8 | + |
| 9 | +namespace Microsoft.PowerShell.EditorServices.Services.Symbols |
| 10 | +{ |
| 11 | + internal static class RegionVisitor |
| 12 | + { |
| 13 | + // This regular expression are used to match lines which mark the start of a region comment in a script. |
| 14 | + // Based on the defaults in the VS Code Language Configuration at; |
| 15 | + // https://github.com/Microsoft/vscode/blob/64186b0a26/extensions/powershell/language-configuration.json#L26-L31 |
| 16 | + // https://github.com/Microsoft/vscode/issues/49070 |
| 17 | + private static readonly Regex s_startRegionTextRegex = new( |
| 18 | + @"^\s*#[rR]egion\b", RegexOptions.Compiled); |
| 19 | + |
| 20 | + internal static void FindRegionsInDocument(ScriptFile file, Func<SymbolReference, AstVisitAction> action) |
| 21 | + { |
| 22 | + Token[] tokens = file.ScriptTokens; |
| 23 | + for (int i = 0; i < tokens.Length; i++) |
| 24 | + { |
| 25 | + Token token = tokens[i]; |
| 26 | + |
| 27 | + // Exclude everything but single-line comments |
| 28 | + if (token.Kind != TokenKind.Comment || |
| 29 | + token.Extent.StartLineNumber != token.Extent.EndLineNumber) |
| 30 | + { |
| 31 | + continue; |
| 32 | + } |
| 33 | + |
| 34 | + // Look for <newline> #region <optional name> |
| 35 | + // Document symbols only care about the symbol start and regex is expensive, |
| 36 | + // so skip checking if region is actually closed with #endregion. |
| 37 | + if (TokenOperations.IsBlockComment(i, tokens) && |
| 38 | + s_startRegionTextRegex.IsMatch(token.Text)) |
| 39 | + { |
| 40 | + action(new SymbolReference( |
| 41 | + SymbolType.Region, |
| 42 | + token.Extent.Text.TrimStart().TrimStart('#'), |
| 43 | + token.Extent.Text, |
| 44 | + token.Extent, |
| 45 | + token.Extent, |
| 46 | + file, |
| 47 | + isDeclaration: true)); |
| 48 | + } |
| 49 | + } |
| 50 | + } |
| 51 | + } |
| 52 | +} |
0 commit comments