提交 e5adae19 编写于 作者: J Jason Malinowski

Don't assume the project is in the workspace

Sometimes the project might not fully be in the workspace yet if we're
asynchronously loading, so let's just fall back and make a fake project.
This should be fine, since right now we don't (yet) have plans for
things that really depend on project state vs. just file locations.
上级 ef0346b7
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor;
using Microsoft.VisualStudio.LanguageServices.Implementation;
namespace Microsoft.VisualStudio.LanguageServices.CSharp.LanguageService
......@@ -15,9 +18,7 @@ public CSharpEditorFactory(CSharpPackage package)
{
}
protected override string ContentTypeName
{
get { return "CSharp"; }
}
protected override string ContentTypeName => ContentTypeNames.CSharpContentType;
protected override string LanguageName => LanguageNames.CSharp;
}
}
......@@ -66,6 +66,7 @@ protected IComponentModel ComponentModel
}
protected abstract string ContentTypeName { get; }
protected abstract string LanguageName { get; }
public void SetEncoding(bool value)
{
......@@ -260,46 +261,63 @@ private void FormatDocumentCreatedFromTemplate(IVsHierarchy hierarchy, uint item
var workspace = ComponentModel.GetService<VisualStudioWorkspace>();
var solution = workspace.CurrentSolution;
ProjectId projectIdToAddTo = null;
foreach (var projectId in solution.ProjectIds)
{
if (workspace.GetHierarchy(projectId) == hierarchy)
{
var documentId = DocumentId.CreateNewId(projectId);
var forkedSolution = solution.AddDocument(DocumentInfo.Create(documentId, filePath, loader: new FileTextLoader(filePath, defaultEncoding: null), filePath: filePath));
var addedDocument = forkedSolution.GetDocument(documentId);
projectIdToAddTo = projectId;
break;
}
}
var rootToFormat = addedDocument.GetSyntaxRootAsync(cancellationToken).WaitAndGetResult(cancellationToken);
if (projectIdToAddTo == null)
{
// We don't have a project for this, so we'll just make up a fake project altogether
var temporaryProject = solution.AddProject(
name: nameof(FormatDocumentCreatedFromTemplate),
assemblyName: nameof(FormatDocumentCreatedFromTemplate),
language: LanguageName);
solution = temporaryProject.Solution;
projectIdToAddTo = temporaryProject.Id;
}
var formattedTextChanges = Formatter.GetFormattedTextChanges(rootToFormat, workspace, addedDocument.Options, cancellationToken);
var formattedText = addedDocument.GetTextAsync(cancellationToken).WaitAndGetResult(cancellationToken).WithChanges(formattedTextChanges);
var documentId = DocumentId.CreateNewId(projectIdToAddTo);
var forkedSolution = solution.AddDocument(DocumentInfo.Create(documentId, filePath, loader: new FileTextLoader(filePath, defaultEncoding: null), filePath: filePath));
var addedDocument = forkedSolution.GetDocument(documentId);
// Ensure the line endings are normalized. The formatter doesn't touch everything if it doesn't need to.
string targetLineEnding = addedDocument.Options.GetOption(FormattingOptions.NewLine);
var rootToFormat = addedDocument.GetSyntaxRootAsync(cancellationToken).WaitAndGetResult(cancellationToken);
var originalText = formattedText;
foreach (var originalLine in originalText.Lines)
{
string originalNewLine = originalText.ToString(CodeAnalysis.Text.TextSpan.FromBounds(originalLine.End, originalLine.EndIncludingLineBreak));
var formattedTextChanges = Formatter.GetFormattedTextChanges(rootToFormat, workspace, addedDocument.Options, cancellationToken);
var formattedText = addedDocument.GetTextAsync(cancellationToken).WaitAndGetResult(cancellationToken).WithChanges(formattedTextChanges);
// Check if we have a line ending, so we don't go adding one to the end if we don't need to.
if (originalNewLine.Length > 0 && originalNewLine != targetLineEnding)
{
var currentLine = formattedText.Lines[originalLine.LineNumber];
var currentSpan = CodeAnalysis.Text.TextSpan.FromBounds(currentLine.End, currentLine.EndIncludingLineBreak);
formattedText = formattedText.WithChanges(new TextChange(currentSpan, targetLineEnding));
}
}
// Ensure the line endings are normalized. The formatter doesn't touch everything if it doesn't need to.
string targetLineEnding = addedDocument.Options.GetOption(FormattingOptions.NewLine);
IOUtilities.PerformIO(() =>
{
using (var textWriter = new StreamWriter(filePath, append: false, encoding: formattedText.Encoding))
{
// We pass null here for cancellation, since cancelling in the middle of the file write would leave the file corrupted
formattedText.Write(textWriter, cancellationToken: CancellationToken.None);
}
});
var originalText = formattedText;
foreach (var originalLine in originalText.Lines)
{
string originalNewLine = originalText.ToString(CodeAnalysis.Text.TextSpan.FromBounds(originalLine.End, originalLine.EndIncludingLineBreak));
// Check if we have a line ending, so we don't go adding one to the end if we don't need to.
if (originalNewLine.Length > 0 && originalNewLine != targetLineEnding)
{
var currentLine = formattedText.Lines[originalLine.LineNumber];
var currentSpan = CodeAnalysis.Text.TextSpan.FromBounds(currentLine.End, currentLine.EndIncludingLineBreak);
formattedText = formattedText.WithChanges(new TextChange(currentSpan, targetLineEnding));
}
}
IOUtilities.PerformIO(() =>
{
using (var textWriter = new StreamWriter(filePath, append: false, encoding: formattedText.Encoding))
{
// We pass null here for cancellation, since cancelling in the middle of the file write would leave the file corrupted
formattedText.Write(textWriter, cancellationToken: CancellationToken.None);
}
});
}
}
}
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Runtime.InteropServices
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Editor
Imports Microsoft.VisualStudio.LanguageServices.Implementation
Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic
......@@ -14,7 +16,13 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic
Protected Overrides ReadOnly Property ContentTypeName As String
Get
Return "Basic"
Return ContentTypeNames.VisualBasicContentType
End Get
End Property
Protected Overrides ReadOnly Property LanguageName As String
Get
Return LanguageNames.VisualBasic
End Get
End Property
End Class
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册