未验证 提交 c6180672 编写于 作者: S Sam Harwell 提交者: GitHub

Merge pull request #34802 from sharwell/regex-features

🧹 Move Regex embedded language to the Features layer
......@@ -970,7 +970,7 @@ public void ReferenceTest15()
<EndOfFile />
</CompilationUnit>
<Diagnostics>
<Diagnostic Message=""{WorkspacesResources.Not_enough_close_parens}"" Span=""[25..25)"" Text="""" />
<Diagnostic Message=""{FeaturesResources.Not_enough_close_parens}"" Span=""[25..25)"" Text="""" />
</Diagnostics>
<Captures>
<Capture Name=""0"" Span=""[10..25)"" Text=""((\w+(\s?)){{2,}}"" />
......@@ -1209,7 +1209,7 @@ public void ReferenceTest18()
<EndOfFile />
</CompilationUnit>
<Diagnostics>
<Diagnostic Message=""{string.Format(WorkspacesResources.Reference_to_undefined_group_name_0, "Open")}"" Span=""[20..24)"" Text=""Open"" />
<Diagnostic Message=""{string.Format(FeaturesResources.Reference_to_undefined_group_name_0, "Open")}"" Span=""[20..24)"" Text=""Open"" />
</Diagnostics>
<Captures>
<Capture Name=""0"" Span=""[10..35)"" Text=""((?'Close-Open'&gt;)[^&lt;&gt;]*)+"" />
......@@ -1847,7 +1847,7 @@ public void ReferenceTest31()
<EndOfFile />
</CompilationUnit>
<Diagnostics>
<Diagnostic Message=""{string.Format(WorkspacesResources.Reference_to_undefined_group_name_0, "Open")}"" Span=""[19..23)"" Text=""Open"" />
<Diagnostic Message=""{string.Format(FeaturesResources.Reference_to_undefined_group_name_0, "Open")}"" Span=""[19..23)"" Text=""Open"" />
</Diagnostics>
<Captures>
<Capture Name=""0"" Span=""[10..26)"" Text=""(?'Close-Open'&gt;)"" />
......
......@@ -44,7 +44,7 @@ void Main()
options: OptionOn(),
diagnosticId: AbstractRegexDiagnosticAnalyzer.DiagnosticId,
diagnosticSeverity: DiagnosticSeverity.Warning,
diagnosticMessage: string.Format(WorkspacesResources.Regex_issue_0, WorkspacesResources.Too_many_close_parens));
diagnosticMessage: string.Format(FeaturesResources.Regex_issue_0, FeaturesResources.Too_many_close_parens));
}
[Fact, Trait(Traits.Feature, Traits.Features.ValidateRegexString)]
......@@ -63,7 +63,7 @@ void Main()
options: OptionOn(),
diagnosticId: AbstractRegexDiagnosticAnalyzer.DiagnosticId,
diagnosticSeverity: DiagnosticSeverity.Warning,
diagnosticMessage: string.Format(WorkspacesResources.Regex_issue_0, WorkspacesResources.Too_many_close_parens));
diagnosticMessage: string.Format(FeaturesResources.Regex_issue_0, FeaturesResources.Too_many_close_parens));
}
[Fact, Trait(Traits.Feature, Traits.Features.ValidateRegexString)]
......
......@@ -8,7 +8,7 @@
namespace Microsoft.CodeAnalysis.Features.EmbeddedLanguages.RegularExpressions
{
internal class RegexEmbeddedLanguageEditorFeatures : RegexEmbeddedLanguageFeatures, IEmbeddedLanguageEditorFeatures
internal class RegexEmbeddedLanguageEditorFeatures : RegexEmbeddedLanguage, IEmbeddedLanguageEditorFeatures
{
public IBraceMatcher BraceMatcher { get; }
......
......@@ -21,7 +21,7 @@ class c
]]></Document>, showCompletionInArgumentLists:=showCompletionInArgumentLists)
state.SendInvokeCompletionList()
Await state.AssertSelectedCompletionItem("\A", inlineDescription:=WorkspacesResources.Regex_start_of_string_only_short)
Await state.AssertSelectedCompletionItem("\A", inlineDescription:=FeaturesResources.Regex_start_of_string_only_short)
state.SendTab()
Await state.AssertNoCompletionSession()
Assert.Contains("new Regex(""\\A"")", state.GetLineTextFromCaretPosition(), StringComparison.Ordinal)
......@@ -66,7 +66,7 @@ class c
state.SendTypeChars("[")
Await state.AssertSelectedCompletionItem($"[ {WorkspacesResources.Regex_character_group} ]")
Await state.AssertSelectedCompletionItem($"[ {FeaturesResources.Regex_character_group} ]")
state.SendDownKey()
state.SendDownKey()
state.SendDownKey()
......@@ -96,7 +96,7 @@ class c
state.SendTypeChars("\b")
Await state.AssertCompletionSession()
Await state.AssertSelectedCompletionItem("\b", description:=WorkspacesResources.Regex_backspace_character_long)
Await state.AssertSelectedCompletionItem("\b", description:=FeaturesResources.Regex_backspace_character_long)
End Using
End Function
......@@ -117,7 +117,7 @@ class c
state.SendTypeChars("\b")
Await state.AssertCompletionSession()
Await state.AssertSelectedCompletionItem("\b", description:=WorkspacesResources.Regex_word_boundary_long)
Await state.AssertSelectedCompletionItem("\b", description:=FeaturesResources.Regex_word_boundary_long)
End Using
End Function
......
......@@ -40,7 +40,7 @@ end class
state.SendTypeChars("[")
Await state.AssertSelectedCompletionItem($"[ {WorkspacesResources.Regex_character_group} ]")
Await state.AssertSelectedCompletionItem($"[ {FeaturesResources.Regex_character_group} ]")
state.SendDownKey()
state.SendDownKey()
state.SendDownKey()
......
......@@ -37,7 +37,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.EmbeddedLanguages
options:=OptionOn(),
diagnosticId:=AbstractRegexDiagnosticAnalyzer.DiagnosticId,
diagnosticSeverity:=DiagnosticSeverity.Warning,
diagnosticMessage:=String.Format(WorkspacesResources.Regex_issue_0, WorkspacesResources.Too_many_close_parens))
diagnosticMessage:=String.Format(FeaturesResources.Regex_issue_0, FeaturesResources.Too_many_close_parens))
End Function
<Fact, Trait(Traits.Feature, Traits.Features.ValidateRegexString)>
......@@ -53,7 +53,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.EmbeddedLanguages
options:=OptionOn(),
diagnosticId:=AbstractRegexDiagnosticAnalyzer.DiagnosticId,
diagnosticSeverity:=DiagnosticSeverity.Warning,
diagnosticMessage:=String.Format(WorkspacesResources.Regex_issue_0, WorkspacesResources.Too_many_close_parens))
diagnosticMessage:=String.Format(FeaturesResources.Regex_issue_0, FeaturesResources.Too_many_close_parens))
End Function
End Class
End Namespace
......@@ -20,7 +20,7 @@ protected AbstractEmbeddedLanguageFeaturesProvider(EmbeddedLanguageInfo info) :
{
Languages = ImmutableArray.Create<IEmbeddedLanguage>(
new DateAndTimeEmbeddedLanguageFeatures(info),
new RegexEmbeddedLanguageFeatures(this, info),
new RegexEmbeddedLanguage(this, info),
new FallbackEmbeddedLanguage(info));
}
......
......@@ -24,8 +24,8 @@ internal abstract class AbstractRegexDiagnosticAnalyzer : AbstractBuiltInCodeSty
protected AbstractRegexDiagnosticAnalyzer(EmbeddedLanguageInfo info)
: base(DiagnosticId,
RegularExpressionsOptions.ReportInvalidRegexPatterns,
new LocalizableResourceString(nameof(WorkspacesResources.Regex_issue_0), WorkspacesResources.ResourceManager, typeof(WorkspacesResources)),
new LocalizableResourceString(nameof(WorkspacesResources.Regex_issue_0), WorkspacesResources.ResourceManager, typeof(WorkspacesResources)))
new LocalizableResourceString(nameof(FeaturesResources.Regex_issue_0), FeaturesResources.ResourceManager, typeof(FeaturesResources)),
new LocalizableResourceString(nameof(FeaturesResources.Regex_issue_0), FeaturesResources.ResourceManager, typeof(FeaturesResources)))
{
_info = info;
}
......
......@@ -13,7 +13,7 @@ internal partial class RegexEmbeddedCompletionProvider
{
private readonly struct EmbeddedCompletionContext
{
private readonly RegexEmbeddedLanguageFeatures _language;
private readonly RegexEmbeddedLanguage _language;
private readonly CompletionContext _context;
private readonly HashSet<string> _names;
......@@ -24,7 +24,7 @@ internal partial class RegexEmbeddedCompletionProvider
public readonly List<RegexItem> Items;
public EmbeddedCompletionContext(
RegexEmbeddedLanguageFeatures language,
RegexEmbeddedLanguage language,
CompletionContext context,
RegexTree tree,
SyntaxToken stringToken)
......
......@@ -13,7 +13,7 @@
namespace Microsoft.CodeAnalysis.EmbeddedLanguages.RegularExpressions
{
using static WorkspacesResources;
using static FeaturesResources;
/// <summary>
/// Minimal copy of https://github.com/dotnet/corefx/blob/master/src/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCharClass.cs
......
......@@ -9,7 +9,6 @@
using Microsoft.CodeAnalysis.DocumentHighlighting;
using Microsoft.CodeAnalysis.EmbeddedLanguages.Common;
using Microsoft.CodeAnalysis.EmbeddedLanguages.RegularExpressions;
using Microsoft.CodeAnalysis.EmbeddedLanguages.RegularExpressions.LanguageServices;
using Microsoft.CodeAnalysis.EmbeddedLanguages.VirtualChars;
using Microsoft.CodeAnalysis.Text;
......
......@@ -16,7 +16,7 @@
namespace Microsoft.CodeAnalysis.Features.EmbeddedLanguages.RegularExpressions
{
using static WorkspacesResources;
using static FeaturesResources;
using RegexToken = EmbeddedSyntaxToken<RegexKind>;
internal partial class RegexEmbeddedCompletionProvider : CompletionProvider
......@@ -32,9 +32,9 @@ internal partial class RegexEmbeddedCompletionProvider : CompletionProvider
CompletionItemRules.Default.WithSelectionBehavior(CompletionItemSelectionBehavior.SoftSelection)
.WithFilterCharacterRule(CharacterSetModificationRule.Create(CharacterSetModificationKind.Replace, new char[] { }));
private readonly RegexEmbeddedLanguageFeatures _language;
private readonly RegexEmbeddedLanguage _language;
public RegexEmbeddedCompletionProvider(RegexEmbeddedLanguageFeatures language)
public RegexEmbeddedCompletionProvider(RegexEmbeddedLanguage language)
=> _language = language;
public override bool ShouldTriggerCompletion(SourceText text, int caretPosition, CompletionTrigger trigger, OptionSet options)
......
......@@ -5,22 +5,37 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Classification.Classifiers;
using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.DocumentHighlighting;
using Microsoft.CodeAnalysis.EmbeddedLanguages.LanguageServices;
using Microsoft.CodeAnalysis.EmbeddedLanguages.RegularExpressions;
using Microsoft.CodeAnalysis.EmbeddedLanguages.RegularExpressions.LanguageServices;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Shared.Extensions;
namespace Microsoft.CodeAnalysis.EmbeddedLanguages.RegularExpressions.LanguageServices
namespace Microsoft.CodeAnalysis.Features.EmbeddedLanguages.RegularExpressions
{
internal class RegexEmbeddedLanguage : IEmbeddedLanguage
internal class RegexEmbeddedLanguage : IEmbeddedLanguageFeatures
{
public readonly EmbeddedLanguageInfo Info;
private readonly AbstractEmbeddedLanguageFeaturesProvider _provider;
public ISyntaxClassifier Classifier { get; }
public IDocumentHighlightsService DocumentHighlightsService { get; }
public CompletionProvider CompletionProvider { get; }
public RegexEmbeddedLanguage(EmbeddedLanguageInfo info)
public RegexEmbeddedLanguage(
AbstractEmbeddedLanguageFeaturesProvider provider,
EmbeddedLanguageInfo info)
{
Info = info;
Classifier = new RegexSyntaxClassifier(info);
_provider = provider;
DocumentHighlightsService = new RegexDocumentHighlightsService(this);
CompletionProvider = new RegexEmbeddedCompletionProvider(this);
}
internal async Task<(RegexTree tree, SyntaxToken token)> TryGetTreeAndTokenAtPositionAsync(
......@@ -45,5 +60,8 @@ public RegexEmbeddedLanguage(EmbeddedLanguageInfo info)
document, position, cancellationToken).ConfigureAwait(false);
return tree;
}
public string EscapeText(string text, SyntaxToken token)
=> _provider.EscapeText(text, token);
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.DocumentHighlighting;
using Microsoft.CodeAnalysis.EmbeddedLanguages.LanguageServices;
using Microsoft.CodeAnalysis.EmbeddedLanguages.RegularExpressions.LanguageServices;
namespace Microsoft.CodeAnalysis.Features.EmbeddedLanguages.RegularExpressions
{
internal class RegexEmbeddedLanguageFeatures : RegexEmbeddedLanguage, IEmbeddedLanguageFeatures
{
private readonly AbstractEmbeddedLanguageFeaturesProvider _provider;
public IDocumentHighlightsService DocumentHighlightsService { get; }
public CompletionProvider CompletionProvider { get; }
public RegexEmbeddedLanguageFeatures(
AbstractEmbeddedLanguageFeaturesProvider provider,
EmbeddedLanguageInfo info) : base(info)
{
_provider = provider;
DocumentHighlightsService = new RegexDocumentHighlightsService(this);
CompletionProvider = new RegexEmbeddedCompletionProvider(this);
}
public string EscapeText(string text, SyntaxToken token)
=> _provider.EscapeText(text, token);
}
}
......@@ -161,7 +161,7 @@ private ImmutableArray<RegexTrivia> ScanLeadingTrivia(bool allowTrivia, RegexOpt
if (Position == Text.Length)
{
var diagnostics = ImmutableArray.Create(new EmbeddedDiagnostic(
WorkspacesResources.Unterminated_regex_comment,
FeaturesResources.Unterminated_regex_comment,
GetTextSpan(start, Position)));
return CreateTrivia(RegexKind.CommentTrivia, GetSubPatternToCurrentPos(start), diagnostics);
}
......@@ -248,7 +248,7 @@ private bool IsBlank(VirtualChar ch)
if (!RegexCharClass.IsEscapeCategory(category))
{
token = token.AddDiagnosticIfNone(new EmbeddedDiagnostic(
string.Format(WorkspacesResources.Unknown_property_0, category),
string.Format(FeaturesResources.Unknown_property_0, category),
token.GetSpan()));
}
......@@ -301,7 +301,7 @@ private static bool IsEscapeCategoryChar(VirtualChar ch)
if (error)
{
token = token.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Capture_group_numbers_must_be_less_than_or_equal_to_Int32_MaxValue,
FeaturesResources.Capture_group_numbers_must_be_less_than_or_equal_to_Int32_MaxValue,
token.GetSpan()));
}
......@@ -393,7 +393,7 @@ public RegexToken ScanHexCharacters(int count)
if (length != count)
{
result = result.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Insufficient_hexadecimal_digits,
FeaturesResources.Insufficient_hexadecimal_digits,
GetTextSpan(beforeSlash, Position)));
}
......
......@@ -518,7 +518,7 @@ private RegexExpressionNode ParseZeroOrOneQuantifier(RegexPrimaryExpressionNode
if (val2 < val1)
{
secondNumberTokenLocal = secondNumberTokenLocal.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Illegal_x_y_with_x_less_than_y,
FeaturesResources.Illegal_x_y_with_x_less_than_y,
secondNumberTokenLocal.GetSpan()));
secondNumberToken = secondNumberTokenLocal;
}
......@@ -594,7 +594,7 @@ private RegexPrimaryExpressionNode ParsePossibleUnexpectedNumericQuantifier(Rege
private RegexPrimaryExpressionNode ParseUnexpectedCloseParenToken()
{
var token = _currentToken.With(kind: RegexKind.TextToken).AddDiagnosticIfNone(
new EmbeddedDiagnostic(WorkspacesResources.Too_many_close_parens, _currentToken.GetSpan()));
new EmbeddedDiagnostic(FeaturesResources.Too_many_close_parens, _currentToken.GetSpan()));
// Technically, since an error occurred, we can do whatever we want here. However,
// the spirit of the native parser is that top level sequence elements are allowed
......@@ -660,7 +660,7 @@ private RegexToken ParseGroupingCloseParen()
default:
return CreateMissingToken(RegexKind.CloseParenToken).AddDiagnosticIfNone(
new EmbeddedDiagnostic(WorkspacesResources.Not_enough_close_parens, GetTokenStartPositionSpan(_currentToken)));
new EmbeddedDiagnostic(FeaturesResources.Not_enough_close_parens, GetTokenStartPositionSpan(_currentToken)));
}
}
......@@ -743,7 +743,7 @@ private RegexGroupingNode ParseGroupQuestion(RegexToken openParenToken, RegexTok
{
// Native parser reports "Unrecognized grouping construct", *except* for (?)
openParenToken = openParenToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Unrecognized_grouping_construct,
FeaturesResources.Unrecognized_grouping_construct,
openParenToken.GetSpan()));
}
......@@ -788,7 +788,7 @@ private RegexConditionalGroupingNode ParseConditionalGrouping(RegexToken openPar
if (!HasCapture((int)capture.Value))
{
capture = capture.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Reference_to_undefined_group,
FeaturesResources.Reference_to_undefined_group,
capture.GetSpan()));
}
}
......@@ -796,7 +796,7 @@ private RegexConditionalGroupingNode ParseConditionalGrouping(RegexToken openPar
{
innerCloseParenToken = CreateMissingToken(RegexKind.CloseParenToken);
capture = capture.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Malformed,
FeaturesResources.Malformed,
capture.GetSpan()));
MoveBackBeforePreviousScan();
}
......@@ -873,14 +873,14 @@ private void MoveBackBeforePreviousScan()
else
{
openParenToken = openParenToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Alternation_conditions_cannot_be_comments,
FeaturesResources.Alternation_conditions_cannot_be_comments,
openParenToken.GetSpan()));
}
}
else if (_lexer.IsAt("(?'"))
{
openParenToken = openParenToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Alternation_conditions_do_not_capture_and_cannot_be_named,
FeaturesResources.Alternation_conditions_do_not_capture_and_cannot_be_named,
openParenToken.GetSpan()));
}
else if (_lexer.IsAt("(?<"))
......@@ -889,7 +889,7 @@ private void MoveBackBeforePreviousScan()
!_lexer.IsAt("(?<="))
{
openParenToken = openParenToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Alternation_conditions_do_not_capture_and_cannot_be_named,
FeaturesResources.Alternation_conditions_do_not_capture_and_cannot_be_named,
openParenToken.GetSpan()));
}
}
......@@ -930,7 +930,7 @@ private RegexExpressionNode CheckConditionalAlternation(RegexExpressionNode resu
return new RegexAlternationNode(
topAlternation.Left,
topAlternation.BarToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Too_many_bars_in_conditional_grouping,
FeaturesResources.Too_many_bars_in_conditional_grouping,
topAlternation.BarToken.GetSpan())),
topAlternation.Right);
}
......@@ -971,7 +971,7 @@ private RegexExpressionNode CheckConditionalAlternation(RegexExpressionNode resu
if (_lexer.Position == _lexer.Text.Length)
{
openParenToken = openParenToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Unrecognized_grouping_construct,
FeaturesResources.Unrecognized_grouping_construct,
GetSpan(openParenToken, openToken)));
}
......@@ -992,7 +992,7 @@ private RegexExpressionNode CheckConditionalAlternation(RegexExpressionNode resu
else
{
openParenToken = openParenToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Invalid_group_name_Group_names_must_begin_with_a_word_character,
FeaturesResources.Invalid_group_name_Group_names_must_begin_with_a_word_character,
GetTokenSpanIncludingEOF(_currentToken)));
// If we weren't at the end of the text, go back to before whatever character
......@@ -1005,7 +1005,7 @@ private RegexExpressionNode CheckConditionalAlternation(RegexExpressionNode resu
if (capture.Kind == RegexKind.NumberToken && (int)capture.Value == 0)
{
capture = capture.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Capture_number_cannot_be_zero,
FeaturesResources.Capture_number_cannot_be_zero,
capture.GetSpan()));
}
......@@ -1039,13 +1039,13 @@ private RegexToken ParseCaptureGroupingCloseToken(ref RegexToken openParenToken,
if (_currentToken.Kind == RegexKind.EndOfFile)
{
openParenToken = openParenToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Unrecognized_grouping_construct,
FeaturesResources.Unrecognized_grouping_construct,
GetSpan(openParenToken, openToken)));
}
else
{
openParenToken = openParenToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Invalid_group_name_Group_names_must_begin_with_a_word_character,
FeaturesResources.Invalid_group_name_Group_names_must_begin_with_a_word_character,
_currentToken.GetSpan()));
// Rewind to where we were before seeing this bogus character.
......@@ -1069,7 +1069,7 @@ private RegexToken ParseCaptureGroupingCloseToken(ref RegexToken openParenToken,
ConsumeCurrentToken(allowTrivia: false);
openParenToken = openParenToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Invalid_group_name_Group_names_must_begin_with_a_word_character,
FeaturesResources.Invalid_group_name_Group_names_must_begin_with_a_word_character,
GetTokenSpanIncludingEOF(_currentToken)));
// If we weren't at the end of the text, go back to before whatever character
......@@ -1105,7 +1105,7 @@ private void CheckCapture(ref RegexToken captureToken)
if (!HasCapture(val))
{
captureToken = captureToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
string.Format(WorkspacesResources.Reference_to_undefined_group_number_0, val),
string.Format(FeaturesResources.Reference_to_undefined_group_number_0, val),
captureToken.GetSpan()));
}
}
......@@ -1115,7 +1115,7 @@ private void CheckCapture(ref RegexToken captureToken)
if (!HasCapture(val))
{
captureToken = captureToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
string.Format(WorkspacesResources.Reference_to_undefined_group_name_0, val),
string.Format(FeaturesResources.Reference_to_undefined_group_name_0, val),
captureToken.GetSpan()));
}
}
......@@ -1162,7 +1162,7 @@ private RegexNonBacktrackingGroupingNode ParseNonBacktrackingGrouping(RegexToken
return new RegexSimpleOptionsGroupingNode(
openParenToken, questionToken, optionsToken,
CreateMissingToken(RegexKind.CloseParenToken).AddDiagnosticIfNone(
new EmbeddedDiagnostic(WorkspacesResources.Unrecognized_grouping_construct, openParenToken.GetSpan())));
new EmbeddedDiagnostic(FeaturesResources.Unrecognized_grouping_construct, openParenToken.GetSpan())));
}
}
......@@ -1261,7 +1261,7 @@ private RegexBaseCharacterClassNode ParseCharacterClass()
if (closeBracketToken.IsMissing)
{
closeBracketToken = closeBracketToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Unterminated_character_class_set,
FeaturesResources.Unterminated_character_class_set,
GetTokenStartPositionSpan(_currentToken)));
}
......@@ -1307,7 +1307,7 @@ private void ParseCharacterClassComponents(ArrayBuilder<RegexExpressionNode> com
leftCh > rightCh)
{
minusToken = minusToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.x_y_range_in_reverse_order,
FeaturesResources.x_y_range_in_reverse_order,
minusToken.GetSpan()));
}
......@@ -1500,7 +1500,7 @@ private RegexPrimaryExpressionNode ParseSingleCharacterClassComponent(bool isFir
if (afterRangeMinus)
{
backslashToken = backslashToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
string.Format(WorkspacesResources.Cannot_include_class_0_in_character_range, nextChar),
string.Format(FeaturesResources.Cannot_include_class_0_in_character_range, nextChar),
GetSpan(backslashToken, _currentToken)));
}
......@@ -1586,7 +1586,7 @@ private RegexPrimaryExpressionNode ParseCharacterClassSubtractionNode(RegexToken
if (_currentToken.Kind != RegexKind.CloseBracketToken && _currentToken.Kind != RegexKind.EndOfFile)
{
minusToken = minusToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.A_subtraction_must_be_the_last_element_in_a_character_class,
FeaturesResources.A_subtraction_must_be_the_last_element_in_a_character_class,
GetTokenStartPositionSpan(minusToken)));
}
......@@ -1608,7 +1608,7 @@ private RegexEscapeNode ParseEscape(RegexToken backslashToken, bool allowTriviaA
if (_currentToken.Kind == RegexKind.EndOfFile)
{
backslashToken = backslashToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Illegal_backslash_at_end_of_pattern,
FeaturesResources.Illegal_backslash_at_end_of_pattern,
backslashToken.GetSpan()));
return new RegexSimpleEscapeNode(backslashToken, CreateMissingToken(RegexKind.TextToken));
}
......@@ -1654,7 +1654,7 @@ private RegexEscapeNode ParseBasicBackslash(RegexToken backslashToken, bool allo
if (_currentToken.Kind == RegexKind.EndOfFile)
{
backslashToken = backslashToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Illegal_backslash_at_end_of_pattern,
FeaturesResources.Illegal_backslash_at_end_of_pattern,
backslashToken.GetSpan()));
return new RegexSimpleEscapeNode(backslashToken, CreateMissingToken(RegexKind.TextToken));
}
......@@ -1784,7 +1784,7 @@ private RegexEscapeNode ParsePossibleKCaptureEscape(RegexToken backslashToken, b
if (openToken.IsMissing)
{
backslashToken = backslashToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Malformed_named_back_reference,
FeaturesResources.Malformed_named_back_reference,
GetSpan(backslashToken, typeToken)));
return new RegexSimpleEscapeNode(backslashToken, typeToken.With(kind: RegexKind.TextToken));
}
......@@ -1883,7 +1883,7 @@ private RegexEscapeNode ParseCharEscape(RegexToken backslashToken, bool allowTri
if (!HasOption(_options, RegexOptions.ECMAScript) && RegexCharClass.IsWordChar(ch))
{
typeToken = typeToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
string.Format(WorkspacesResources.Unrecognized_escape_sequence_0, ch),
string.Format(FeaturesResources.Unrecognized_escape_sequence_0, ch),
typeToken.GetSpan()));
}
......@@ -1915,7 +1915,7 @@ private RegexControlEscapeNode ParseControlEscape(RegexToken backslashToken, boo
if (_currentToken.Kind == RegexKind.EndOfFile)
{
typeToken = typeToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Missing_control_character,
FeaturesResources.Missing_control_character,
typeToken.GetSpan()));
return new RegexControlEscapeNode(backslashToken, typeToken, CreateMissingToken(RegexKind.TextToken));
}
......@@ -1955,7 +1955,7 @@ private RegexControlEscapeNode ParseControlEscape(RegexToken backslashToken, boo
else
{
typeToken = typeToken.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Unrecognized_control_character,
FeaturesResources.Unrecognized_control_character,
_currentToken.GetSpan()));
// Don't consume the bogus control character.
......@@ -2001,7 +2001,7 @@ private RegexEscapeNode ParseCategoryEscape(RegexToken backslash, bool allowTriv
if (_lexer.Text.Length - _lexer.Position < "{x}".Length)
{
message = WorkspacesResources.Incomplete_character_escape;
message = FeaturesResources.Incomplete_character_escape;
return false;
}
......@@ -2010,7 +2010,7 @@ private RegexEscapeNode ParseCategoryEscape(RegexToken backslash, bool allowTriv
if (_currentToken.Kind != RegexKind.OpenBraceToken)
{
message = WorkspacesResources.Malformed_character_escape;
message = FeaturesResources.Malformed_character_escape;
return false;
}
......@@ -2021,13 +2021,13 @@ private RegexEscapeNode ParseCategoryEscape(RegexToken backslash, bool allowTriv
ConsumeCurrentToken(allowTrivia: false);
if (_currentToken.Kind != RegexKind.CloseBraceToken)
{
message = WorkspacesResources.Incomplete_character_escape;
message = FeaturesResources.Incomplete_character_escape;
return false;
}
if (category == null)
{
message = WorkspacesResources.Unknown_property;
message = FeaturesResources.Unknown_property;
return false;
}
......@@ -2051,13 +2051,13 @@ private void CheckQuantifierExpression(RegexExpressionNode current, ref RegexTok
current.Kind == RegexKind.SimpleOptionsGrouping)
{
token = token.AddDiagnosticIfNone(new EmbeddedDiagnostic(
WorkspacesResources.Quantifier_x_y_following_nothing, token.GetSpan()));
FeaturesResources.Quantifier_x_y_following_nothing, token.GetSpan()));
}
else if (current is RegexQuantifierNode ||
current is RegexLazyQuantifierNode)
{
token = token.AddDiagnosticIfNone(new EmbeddedDiagnostic(
string.Format(WorkspacesResources.Nested_quantifier_0, token.VirtualChars.First()), token.GetSpan()));
string.Format(FeaturesResources.Nested_quantifier_0, token.VirtualChars.First()), token.GetSpan()));
}
}
}
......
......@@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.EmbeddedLanguages.RegularExpressions.LanguageServices;
namespace Microsoft.CodeAnalysis.EmbeddedLanguages.LanguageServices
{
......@@ -16,9 +15,7 @@ internal abstract class AbstractEmbeddedLanguagesProvider : IEmbeddedLanguagesPr
protected AbstractEmbeddedLanguagesProvider(EmbeddedLanguageInfo info)
{
Languages = ImmutableArray.Create<IEmbeddedLanguage>(
new RegexEmbeddedLanguage(info),
new FallbackEmbeddedLanguage(info));
Languages = ImmutableArray.Create<IEmbeddedLanguage>(new FallbackEmbeddedLanguage(info));
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册