Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,16 @@ public sealed class CodeWriter
private int _currentLineIndex;
private int _currentLineCharacterIndex;

public CodeWriter()
public CodeWriter() : this(Environment.NewLine, 4, false)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public CodeWriter() : this(Environment.NewLine, 4, false)
public CodeWriter() : this(Environment.NewLine, 4, indentWithTabs: false)

{
NewLine = Environment.NewLine;
}

public CodeWriter(string newLine, int tabSize, bool indentWithTabs)
{
NewLine = newLine;
TabSize = tabSize;
IndentWithTabs = indentWithTabs;

_builder = new StringBuilder();
}

Expand All @@ -47,6 +54,10 @@ public string NewLine
}
}

public int TabSize { get; set; }
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public setters?


public bool IndentWithTabs { get; set; }

public SourceLocation Location => new SourceLocation(_absoluteIndex, _currentLineIndex, _currentLineCharacterIndex);

public char this[int index]
Expand All @@ -62,15 +73,40 @@ public char this[int index]
}
}

// Internal for testing.
internal CodeWriter Indent(int size)
public CodeWriter Indent(int size)
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made this public. Otherwise things in Extensions.1_X projects etc were complaining because we share CodeWriterExtensions.cs as a shared source and it uses this method.

{
if (Length == 0 || this[Length - 1] == '\n')
{
_builder.Append(' ', size);
var actualSize = 0;
if (IndentWithTabs)
{
// Avoid writing directly to the StringBuilder here, that will throw off the manual indexing
// done by the base class.
var tabs = size / TabSize;
actualSize += tabs;
for (var i = 0; i < tabs; i++)
{
_builder.Append("\t");
}

var spaces = size % TabSize;
actualSize += spaces;
for (var i = 0; i < spaces; i++)
{
_builder.Append(" ");
}
}
else
{
actualSize = size;
for (var i = 0; i < size; i++)
{
_builder.Append(" ");
}
}

_currentLineCharacterIndex += size;
_absoluteIndex += size;
_currentLineCharacterIndex += actualSize;
_absoluteIndex += actualSize;
}

return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,29 +48,7 @@ public static CodeWriter WritePadding(this CodeWriter writer, int offset, Source
var basePadding = CalculatePadding();
var resolvedPadding = Math.Max(basePadding - offset, 0);

if (context.Options.IndentWithTabs)
{
// Avoid writing directly to the StringBuilder here, that will throw off the manual indexing
// done by the base class.
var tabs = resolvedPadding / context.Options.IndentSize;
for (var i = 0; i < tabs; i++)
{
writer.Write("\t");
}

var spaces = resolvedPadding % context.Options.IndentSize;
for (var i = 0; i < spaces; i++)
{
writer.Write(" ");
}
}
else
{
for (var i = 0; i < resolvedPadding; i++)
{
writer.Write(" ");
}
}
writer.Indent(resolvedPadding);

return writer;

Expand All @@ -86,7 +64,7 @@ int CalculatePadding()
}
else if (@char == '\t')
{
spaceCount += context.Options.IndentSize;
spaceCount += writer.TabSize;
}
else
{
Expand Down Expand Up @@ -569,11 +547,11 @@ public struct CSharpCodeWritingScope : IDisposable
private int _tabSize;
private int _startIndent;

public CSharpCodeWritingScope(CodeWriter writer, int tabSize = 4, bool autoSpace = true)
public CSharpCodeWritingScope(CodeWriter writer, bool autoSpace = true)
{
_writer = writer;
_autoSpace = autoSpace;
_tabSize = tabSize;
_tabSize = writer.TabSize;
_startIndent = -1; // Set in WriteStartScope

WriteStartScope();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public override RazorCSharpDocument WriteDocument(RazorCodeDocument codeDocument
}

var context = new DefaultCodeRenderingContext(
new CodeWriter(),
new CodeWriter(Environment.NewLine, _options.IndentSize, _options.IndentWithTabs),
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Environment.NewLine should also eventually come from options.

_codeTarget.CreateNodeWriter(),
codeDocument,
documentNode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Razor;
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
using Microsoft.Extensions.Options;

namespace Microsoft.AspNetCore.Razor.LanguageServer
{
Expand All @@ -17,12 +18,14 @@ internal class DefaultProjectSnapshotManagerAccessor : ProjectSnapshotManagerAcc
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly IEnumerable<ProjectSnapshotChangeTrigger> _changeTriggers;
private readonly FilePathNormalizer _filePathNormalizer;
private readonly IOptionsMonitor<RazorLSPOptions> _optionsMonitor;
private ProjectSnapshotManagerBase _instance;

public DefaultProjectSnapshotManagerAccessor(
ForegroundDispatcher foregroundDispatcher,
IEnumerable<ProjectSnapshotChangeTrigger> changeTriggers,
FilePathNormalizer filePathNormalizer)
FilePathNormalizer filePathNormalizer,
IOptionsMonitor<RazorLSPOptions> optionsMonitor)
{
if (foregroundDispatcher == null)
{
Expand All @@ -39,9 +42,15 @@ public DefaultProjectSnapshotManagerAccessor(
throw new ArgumentNullException(nameof(filePathNormalizer));
}

if (optionsMonitor is null)
{
throw new ArgumentNullException(nameof(optionsMonitor));
}

_foregroundDispatcher = foregroundDispatcher;
_changeTriggers = changeTriggers;
_filePathNormalizer = filePathNormalizer;
_optionsMonitor = optionsMonitor;
}

public override ProjectSnapshotManagerBase Instance
Expand All @@ -53,7 +62,7 @@ public override ProjectSnapshotManagerBase Instance
var services = AdhocServices.Create(
workspaceServices: new[]
{
new RemoteProjectSnapshotProjectEngineFactory(_filePathNormalizer)
new RemoteProjectSnapshotProjectEngineFactory(_filePathNormalizer, _optionsMonitor)
},
razorLanguageServices: Enumerable.Empty<ILanguageService>());
var workspace = new AdhocWorkspace(services);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ public async override Task<RazorLSPOptions> GetLatestOptionsAsync()
{
Items = new[]
{
new ConfigurationItem()
{
Section = "editor"
},
new ConfigurationItem()
{
Section = "razor"
Expand All @@ -49,16 +53,22 @@ public async override Task<RazorLSPOptions> GetLatestOptionsAsync()
};

var result = await _server.Client.SendRequest<ConfigurationParams, object[]>("workspace/configuration", request);
if (result == null || result.Length < 1 || result[0] == null)
if (result == null || result.Length < 2 || result[0] == null)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What makes 2 the expected length, and as a corollary, why was it one before?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spec says the result should be the same length as the number of ConfigurationItems we pass in. I'll leave a comment for future us.

{
_logger.LogWarning("Client failed to provide the expected configuration.");
return null;
}

var jsonString = result[0].ToString();
var builder = new ConfigurationBuilder();
using var stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
builder.AddJsonStream(stream);

var editorJsonString = result[0].ToString();
using var editorStream = new MemoryStream(Encoding.UTF8.GetBytes(editorJsonString));
builder.AddJsonStream(editorStream);

var razorJsonString = result[1].ToString();
using var razorStream = new MemoryStream(Encoding.UTF8.GetBytes(razorJsonString));
builder.AddJsonStream(razorStream);

var config = builder.Build();

var instance = BuildOptions(config);
Expand All @@ -83,7 +93,19 @@ private RazorLSPOptions BuildOptions(IConfiguration config)
enableFormatting = parsedEnableFormatting;
}

return new RazorLSPOptions(trace, enableFormatting);
var tabSize = instance.TabSize;
if (int.TryParse(config["tabSize"], out var parsedTabSize))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a guarantee that config will always have a tabSize?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Guarantee is a strong word but we can expect vscode to do the right thing. Moreover, if it is not there it still won't throw. The default implementation of IConfiguration will just return null.

{
tabSize = parsedTabSize;
}

var insertSpaces = instance.InsertSpaces;
if (bool.TryParse(config["insertSpaces"], out var parsedInsertSpaces))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

{
insertSpaces = parsedInsertSpaces;
}

return new RazorLSPOptions(trace, enableFormatting, tabSize, insertSpaces);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,26 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer
{
internal class RazorLSPOptions : IEquatable<RazorLSPOptions>
{
public RazorLSPOptions(Trace trace, bool enableFormatting)
public RazorLSPOptions(Trace trace, bool enableFormatting, int tabSize, bool insertSpaces)
{
Trace = trace;
EnableFormatting = enableFormatting;
TabSize = tabSize;
InsertSpaces = insertSpaces;
}

public static RazorLSPOptions Default => new RazorLSPOptions(trace: default, enableFormatting: true);
public static RazorLSPOptions Default => new RazorLSPOptions(trace: default, enableFormatting: true, tabSize: 4, insertSpaces: true);

public Trace Trace { get; }

public LogLevel MinLogLevel => GetLogLevelForTrace(Trace);

public bool EnableFormatting { get; }

public int TabSize { get; }

public bool InsertSpaces { get; }

public static LogLevel GetLogLevelForTrace(Trace trace)
{
return trace switch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Microsoft.AspNetCore.Razor.LanguageServer.Common;
using Microsoft.AspNetCore.Razor.LanguageServer.ProjectSystem;
using Microsoft.CodeAnalysis.Razor;
using Microsoft.Extensions.Options;

namespace Microsoft.AspNetCore.Razor.LanguageServer
{
Expand All @@ -15,16 +16,23 @@ internal class RemoteProjectSnapshotProjectEngineFactory : DefaultProjectSnapsho
public static readonly IFallbackProjectEngineFactory FallbackProjectEngineFactory = new FallbackProjectEngineFactory();

private readonly FilePathNormalizer _filePathNormalizer;
private readonly IOptionsMonitor<RazorLSPOptions> _optionsMonitor;

public RemoteProjectSnapshotProjectEngineFactory(FilePathNormalizer filePathNormalizer) :
public RemoteProjectSnapshotProjectEngineFactory(FilePathNormalizer filePathNormalizer, IOptionsMonitor<RazorLSPOptions> optionsMonitor) :
base(FallbackProjectEngineFactory, ProjectEngineFactories.Factories)
{
if (filePathNormalizer == null)
{
throw new ArgumentNullException(nameof(filePathNormalizer));
}

if (optionsMonitor is null)
{
throw new ArgumentNullException(nameof(optionsMonitor));
}

_filePathNormalizer = filePathNormalizer;
_optionsMonitor = optionsMonitor;
}

public override RazorProjectEngine Create(
Expand All @@ -39,7 +47,37 @@ public override RazorProjectEngine Create(
}

var remoteFileSystem = new RemoteRazorProjectFileSystem(defaultFileSystem.Root, _filePathNormalizer);
return base.Create(configuration, remoteFileSystem, configure);
return base.Create(configuration, remoteFileSystem, Configure);

void Configure(RazorProjectEngineBuilder builder)
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not completely sure if this is the right place to wire this up.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not awful

{
configure(builder);
builder.Features.Add(new RemoteCodeGenerationOptionsFeature(_optionsMonitor));
}
}

private class RemoteCodeGenerationOptionsFeature : RazorEngineFeatureBase, IConfigureRazorCodeGenerationOptionsFeature
{
private readonly IOptionsMonitor<RazorLSPOptions> _optionsMonitor;

public RemoteCodeGenerationOptionsFeature(IOptionsMonitor<RazorLSPOptions> optionsMonitor)
{
if (optionsMonitor is null)
{
throw new ArgumentNullException(nameof(optionsMonitor));
}

_optionsMonitor = optionsMonitor;
}

public int Order { get; set; }

public void Configure(RazorCodeGenerationOptionsBuilder options)
{
// We don't need to explicitly subscribe to options changing because this method will be run on every parse.
options.IndentSize = _optionsMonitor.CurrentValue.TabSize;
options.IndentWithTabs = !_optionsMonitor.CurrentValue.InsertSpaces;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,22 @@ public class DefaultRazorConfigurationServiceTest : LanguageServerTestBase
public async Task GetLatestOptionsAsync_ReturnsExpectedOptions()
{
// Arrange
var expectedOptions = new RazorLSPOptions(Trace.Messages, enableFormatting: false);
var jsonString = @"
var expectedOptions = new RazorLSPOptions(Trace.Messages, enableFormatting: false, tabSize: 8, insertSpaces: true);
var editorJsonString = @"
{
""tabSize"": 8,
""insertSpaces"": ""true""
}
".Trim();
var razorJsonString = @"
{
""trace"": ""Messages"",
""format"": {
""enable"": ""false""
}
}
".Trim();
var result = new object[] { jsonString };
var result = new object[] { editorJsonString, razorJsonString };
var languageServer = GetLanguageServer(result);
var configurationService = new DefaultRazorConfigurationService(languageServer, LoggerFactory);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public async Task Handle_FormattingDisabled_ReturnsNull()
private static IOptionsMonitor<RazorLSPOptions> GetOptionsMonitor(bool enableFormatting)
{
var monitor = new Mock<IOptionsMonitor<RazorLSPOptions>>();
monitor.SetupGet(m => m.CurrentValue).Returns(new RazorLSPOptions(default, enableFormatting));
monitor.SetupGet(m => m.CurrentValue).Returns(new RazorLSPOptions(default, enableFormatting, tabSize: 4, insertSpaces: true));
return monitor.Object;
}

Expand Down
Loading