Skip to content

Commit 22e6385

Browse files
Merge branch 'main' into intermediate-nodes
2 parents 1ba5890 + 77a272e commit 22e6385

File tree

7 files changed

+100
-107
lines changed

7 files changed

+100
-107
lines changed

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/CodeGeneration/CodeWriter.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
using System.Text;
1212
using Microsoft.AspNetCore.Razor.PooledObjects;
1313
using Microsoft.CodeAnalysis.Text;
14-
using static System.StringExtensions;
1514

1615
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration;
1716

@@ -508,7 +507,7 @@ public override string ReadToEnd()
508507
return string.Empty;
509508
}
510509

511-
var result = CreateString(_remainingLength, (_page, _chunkIndex, _charIndex), static (destination, state) =>
510+
var result = string.Create(_remainingLength, (_page, _chunkIndex, _charIndex), static (destination, state) =>
512511
{
513512
var (page, chunkIndex, charIndex) = state;
514513

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/DefaultRazorProjectFileSystem.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ protected override string NormalizeAndEnsureValidPath(string path)
127127
var needsSlash = Root[^1] is not '/' && normalizedPath[0] is not '/';
128128
var length = Root.Length + normalizedPath.Length + (needsSlash ? 1 : 0);
129129

130-
return StringExtensions.CreateString(
130+
return string.Create(
131131
length,
132132
state: (Root, normalizedPath, needsSlash),
133133
static (span, state) =>

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Legacy/HtmlTokenizer.cs

Lines changed: 55 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
// Licensed to the .NET Foundation under one or more agreements.
1+
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
#nullable disable
5-
4+
using System.Collections.Frozen;
5+
using System.Collections.Generic;
66
using System.Diagnostics;
77
using Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax;
88
using Microsoft.CodeAnalysis.CSharp;
@@ -14,6 +14,21 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy;
1414
// Tokenizer _loosely_ based on http://dev.w3.org/html5/spec/Overview.html#tokenization
1515
internal class HtmlTokenizer : Tokenizer
1616
{
17+
private static readonly FrozenDictionary<SyntaxKind, SyntaxToken> s_kindToTokenMap = new Dictionary<SyntaxKind, SyntaxToken>()
18+
{
19+
[SyntaxKind.OpenAngle] = SyntaxFactory.Token(SyntaxKind.OpenAngle, "<"),
20+
[SyntaxKind.Bang] = SyntaxFactory.Token(SyntaxKind.Bang, "!"),
21+
[SyntaxKind.ForwardSlash] = SyntaxFactory.Token(SyntaxKind.ForwardSlash, "/"),
22+
[SyntaxKind.QuestionMark] = SyntaxFactory.Token(SyntaxKind.QuestionMark, "?"),
23+
[SyntaxKind.LeftBracket] = SyntaxFactory.Token(SyntaxKind.LeftBracket, "["),
24+
[SyntaxKind.CloseAngle] = SyntaxFactory.Token(SyntaxKind.CloseAngle, ">"),
25+
[SyntaxKind.RightBracket] = SyntaxFactory.Token(SyntaxKind.RightBracket, "]"),
26+
[SyntaxKind.Equals] = SyntaxFactory.Token(SyntaxKind.Equals, "="),
27+
[SyntaxKind.DoubleQuote] = SyntaxFactory.Token(SyntaxKind.DoubleQuote, "\""),
28+
[SyntaxKind.SingleQuote] = SyntaxFactory.Token(SyntaxKind.SingleQuote, "'"),
29+
[SyntaxKind.DoubleHyphen] = SyntaxFactory.Token(SyntaxKind.DoubleHyphen, "--"),
30+
}.ToFrozenDictionary();
31+
1732
public HtmlTokenizer(SeekableTextReader source)
1833
: base(source)
1934
{
@@ -24,23 +39,20 @@ public HtmlTokenizer(SeekableTextReader source)
2439

2540
private new HtmlTokenizerState? CurrentState => (HtmlTokenizerState?)base.CurrentState;
2641

27-
public override SyntaxKind RazorCommentKind
28-
{
29-
get { return SyntaxKind.RazorCommentLiteral; }
30-
}
42+
public override SyntaxKind RazorCommentKind => SyntaxKind.RazorCommentLiteral;
3143

32-
public override SyntaxKind RazorCommentTransitionKind
33-
{
34-
get { return SyntaxKind.RazorCommentTransition; }
35-
}
44+
public override SyntaxKind RazorCommentTransitionKind => SyntaxKind.RazorCommentTransition;
3645

37-
public override SyntaxKind RazorCommentStarKind
38-
{
39-
get { return SyntaxKind.RazorCommentStar; }
40-
}
46+
public override SyntaxKind RazorCommentStarKind => SyntaxKind.RazorCommentStar;
4147

4248
protected override SyntaxToken CreateToken(string content, SyntaxKind type, RazorDiagnostic[] errors)
4349
{
50+
if (errors.Length == 0 && s_kindToTokenMap.TryGetValue(type, out var token))
51+
{
52+
Debug.Assert(token.Content == content);
53+
return token;
54+
}
55+
4456
return SyntaxFactory.Token(type, content, errors);
4557
}
4658

@@ -62,9 +74,10 @@ protected override StateResult Dispatch()
6274
return StarAfterRazorCommentBody();
6375
case HtmlTokenizerState.AtTokenAfterRazorCommentBody:
6476
return AtTokenAfterRazorCommentBody(nextState: StartState);
77+
6578
default:
6679
Debug.Fail("Invalid TokenizerState");
67-
return default(StateResult);
80+
return default;
6881
}
6982
}
7083

@@ -98,20 +111,22 @@ protected override string GetTokenContent(SyntaxKind type)
98111
case SyntaxKind.SingleQuote:
99112
return "'";
100113
case SyntaxKind.Whitespace:
101-
if (Buffer[0] == ' ')
102-
{
103-
return " ";
104-
}
105-
if (Buffer[0] == '\t')
114+
switch (Buffer[0])
106115
{
107-
return "\t";
116+
case ' ':
117+
return " ";
118+
case '\t':
119+
return "\t";
108120
}
121+
109122
break;
123+
110124
case SyntaxKind.NewLine:
111125
if (Buffer[0] == '\n')
112126
{
113127
return "\n";
114128
}
129+
115130
break;
116131
}
117132
}
@@ -196,11 +211,13 @@ private StateResult Text()
196211
return Transition(HtmlTokenizerState.Data, EndToken(SyntaxKind.Text));
197212
}
198213

199-
private SyntaxToken Token()
214+
private SyntaxToken? Token()
200215
{
201216
Debug.Assert(AtToken());
217+
202218
var sym = CurrentCharacter;
203219
TakeCurrent();
220+
204221
switch (sym)
205222
{
206223
case '<':
@@ -227,66 +244,52 @@ private SyntaxToken Token()
227244
Debug.Assert(CurrentCharacter == '-');
228245
TakeCurrent();
229246
return EndToken(SyntaxKind.DoubleHyphen);
247+
230248
default:
231249
Debug.Fail("Unexpected token!");
232250
return EndToken(SyntaxKind.Marker);
233251
}
234252
}
235253

236-
private SyntaxToken Whitespace()
254+
private SyntaxToken? Whitespace()
237255
{
238256
while (SyntaxFacts.IsWhitespace(CurrentCharacter))
239257
{
240258
TakeCurrent();
241259
}
260+
242261
return EndToken(SyntaxKind.Whitespace);
243262
}
244263

245-
private SyntaxToken Newline()
264+
private SyntaxToken? Newline()
246265
{
247266
Debug.Assert(SyntaxFacts.IsNewLine(CurrentCharacter));
267+
248268
// CSharp Spec §2.3.1
249269
var checkTwoCharNewline = CurrentCharacter == '\r';
250270
TakeCurrent();
271+
251272
if (checkTwoCharNewline && CurrentCharacter == '\n')
252273
{
253274
TakeCurrent();
254275
}
276+
255277
return EndToken(SyntaxKind.NewLine);
256278
}
257279

258280
private bool AtToken()
259-
{
260-
switch (CurrentCharacter)
281+
=> CurrentCharacter switch
261282
{
262-
case '<':
263-
case '!':
264-
case '/':
265-
case '?':
266-
case '[':
267-
case '>':
268-
case ']':
269-
case '=':
270-
case '"':
271-
case '\'':
272-
case '@':
273-
return true;
274-
case '-':
275-
return Peek() == '-';
276-
}
277-
278-
return false;
279-
}
283+
'<' or '!' or '/' or '?' or '[' or '>' or ']' or '=' or '"' or '\'' or '@' => true,
284+
'-' => Peek() == '-',
285+
_ => false,
286+
};
280287

281288
private StateResult Transition(HtmlTokenizerState state)
282-
{
283-
return Transition((int)state, result: null);
284-
}
289+
=> Transition((int)state, result: null);
285290

286-
private StateResult Transition(HtmlTokenizerState state, SyntaxToken result)
287-
{
288-
return Transition((int)state, result);
289-
}
291+
private StateResult Transition(HtmlTokenizerState state, SyntaxToken? result)
292+
=> Transition((int)state, result);
290293

291294
private enum HtmlTokenizerState
292295
{

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorProjectFileSystem.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ internal ImmutableArray<RazorProjectItem> FindHierarchicalItems(string basePath,
120120
{
121121
pathMemory = pathMemory[..(index + 1)];
122122

123-
var itemPath = StringExtensions.CreateString(
123+
var itemPath = string.Create(
124124
length: pathMemory.Length + fileName.Length,
125125
state: (pathMemory, fileName),
126126
static (span, state) =>

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Logging/LogMessageFormatter.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Diagnostics;
66
using System.Runtime.CompilerServices;
77
using Microsoft.AspNetCore.Razor;
8-
using static System.StringExtensions;
98

109
namespace Microsoft.CodeAnalysis.Razor.Logging;
1110

@@ -23,7 +22,7 @@ public static string FormatMessage(string message, string categoryName, Exceptio
2322
ref messageLineRangeBuilder, ref exceptionLineRangeBuilder);
2423

2524
// Create the final string.
26-
return CreateString(state.Length, state, static (span, state) =>
25+
return string.Create(state.Length, state, static (span, state) =>
2726
{
2827
Write(state.CategoryNamePart, ref span);
2928

src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LspEditorFeatureDetector.cs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,7 @@ public bool IsLspEditorEnabled()
8686
#pragma warning restore VSTHRD108 // Assert thread affinity unconditionally
8787
}
8888

89-
var useLegacyEditorEnabled = _lazyLegacyEditorEnabled.GetValue(_disposeTokenSource.Token);
90-
91-
if (useLegacyEditorEnabled)
92-
{
93-
_activityLog.LogInfo("Using legacy editor because the option was set to true");
94-
return false;
95-
}
96-
97-
_activityLog.LogInfo("LSP editor is enabled.");
98-
return true;
89+
return !_lazyLegacyEditorEnabled.GetValue(_disposeTokenSource.Token);
9990
}
10091

10192
/// <inheritdoc/>

src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/StringExtensions.cs

Lines changed: 40 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,7 @@ public static bool EndsWith(this string text, char value)
555555
#endif
556556
}
557557

558+
#if !NET
558559
/// <summary>
559560
/// Encapsulates a method that receives a span of objects of type <typeparamref name="T"/>
560561
/// and a state object of type <typeparamref name="TArg"/>.
@@ -573,49 +574,49 @@ public static bool EndsWith(this string text, char value)
573574
/// </param>
574575
public delegate void SpanAction<T, in TArg>(Span<T> span, TArg arg);
575576

576-
/// <summary>
577-
/// Creates a new string with a specific length and initializes it after creation by using the specified callback.
578-
/// </summary>
579-
/// <typeparam name="TState">
580-
/// The type of the element to pass to <paramref name="action"/>.
581-
/// </typeparam>
582-
/// <param name="length">
583-
/// The length of the string to create.
584-
/// </param>
585-
/// <param name="state">
586-
/// The element to pass to <paramref name="action"/>.
587-
/// </param>
588-
/// <param name="action">
589-
/// A callback to initialize the string
590-
/// </param>
591-
/// <returns>
592-
/// The created string.
593-
/// </returns>
594-
/// <remarks>
595-
/// The initial content of the destination span passed to <paramref name="action"/> is undefined.
596-
/// Therefore, it is the delegate's responsibility to ensure that every element of the span is assigned.
597-
/// Otherwise, the resulting string could contain random characters
598-
/// </remarks>
599-
public unsafe static string CreateString<TState>(int length, TState state, SpanAction<char, TState> action)
577+
extension(string)
600578
{
601-
#if NET
602-
return string.Create(length, (action, state), static (span, state) => state.action(span, state.state));
603-
#else
604-
ArgHelper.ThrowIfNegative(length);
605-
606-
if (length == 0)
579+
/// <summary>
580+
/// Creates a new string with a specific length and initializes it after creation by using the specified callback.
581+
/// </summary>
582+
/// <typeparam name="TState">
583+
/// The type of the element to pass to <paramref name="action"/>.
584+
/// </typeparam>
585+
/// <param name="length">
586+
/// The length of the string to create.
587+
/// </param>
588+
/// <param name="state">
589+
/// The element to pass to <paramref name="action"/>.
590+
/// </param>
591+
/// <param name="action">
592+
/// A callback to initialize the string
593+
/// </param>
594+
/// <returns>
595+
/// The created string.
596+
/// </returns>
597+
/// <remarks>
598+
/// The initial content of the destination span passed to <paramref name="action"/> is undefined.
599+
/// Therefore, it is the delegate's responsibility to ensure that every element of the span is assigned.
600+
/// Otherwise, the resulting string could contain random characters.
601+
/// </remarks>
602+
public unsafe static string Create<TState>(int length, TState state, SpanAction<char, TState> action)
607603
{
608-
return string.Empty;
609-
}
604+
ArgHelper.ThrowIfNegative(length);
610605

611-
var result = new string('\0', length);
606+
if (length == 0)
607+
{
608+
return string.Empty;
609+
}
612610

613-
fixed (char* ptr = result)
614-
{
615-
action(new Span<char>(ptr, length), state);
616-
}
611+
var result = new string('\0', length);
617612

618-
return result;
619-
#endif
613+
fixed (char* ptr = result)
614+
{
615+
action(new Span<char>(ptr, length), state);
616+
}
617+
618+
return result;
619+
}
620620
}
621+
#endif
621622
}

0 commit comments

Comments
 (0)