提交 bbbf0735 编写于 作者: C CyrusNajmabadi

Get tooltips working.

上级 8cc9513c
......@@ -7,6 +7,8 @@
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Projection;
using System.Windows.Controls;
using System;
namespace Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.QuickInfo
{
......@@ -34,11 +36,13 @@ internal class ElisionBufferDeferredContent : IDeferredQuickInfoContent
_textEditorFactoryService = textEditorFactoryService;
}
public FrameworkElement Create()
public ContentControl Create()
{
return new ViewHostingControl(CreateView, CreateBuffer);
}
FrameworkElement IDeferredQuickInfoContent.Create() => Create();
private IWpfTextView CreateView(ITextBuffer buffer)
{
var view = _textEditorFactoryService.CreateTextView(
......
......@@ -8,6 +8,7 @@
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
using Roslyn.Utilities;
using System;
namespace Microsoft.CodeAnalysis.Editor.Shared.Extensions
{
......@@ -31,27 +32,55 @@ public static TextBlock ToTextBlock(this TaggedText part, ClassificationTypeMap
return SpecializedCollections.SingletonEnumerable(part).ToTextBlock(typeMap);
}
public static IList<Inline> ToInlines(this IEnumerable<TaggedText> parts, ClassificationTypeMap typeMap)
public static IList<Inline> ToInlines(
this IEnumerable<TaggedText> parts,
ClassificationTypeMap typeMap,
string classificationFormatMap = null,
Action<Run, TaggedText, int> runCallback = null)
{
var formatMap = typeMap.ClassificationFormatMapService.GetClassificationFormatMap("tooltip");
classificationFormatMap = classificationFormatMap ?? "tooltip";
var formatMap = typeMap.ClassificationFormatMapService.GetClassificationFormatMap(classificationFormatMap);
var inlines = new List<Inline>();
var position = 0;
foreach (var part in parts)
{
inlines.Add(part.ToRun(formatMap, typeMap));
var run = part.ToRun(formatMap, typeMap);
runCallback?.Invoke(run, part, position);
inlines.Add(run);
position += part.Text.Length;
}
return inlines;
}
public static TextBlock ToTextBlock(this IEnumerable<TaggedText> parts, ClassificationTypeMap typeMap)
public static TextBlock ToTextBlock(
this IEnumerable<TaggedText> parts,
ClassificationTypeMap typeMap,
string classificationFormatMap = null,
Action<Run, TaggedText, int> runCallback = null)
{
classificationFormatMap = classificationFormatMap ?? "tooltip";
var inlines = parts.ToInlines(typeMap, classificationFormatMap, runCallback);
return inlines.ToTextBlock(typeMap, classificationFormatMap);
}
public static TextBlock ToTextBlock(
this IEnumerable<Inline> inlines,
ClassificationTypeMap typeMap,
string classificationFormatMap = null)
{
var result = new TextBlock() { TextWrapping = TextWrapping.Wrap };
classificationFormatMap = classificationFormatMap ?? "tooltip";
var formatMap = typeMap.ClassificationFormatMapService.GetClassificationFormatMap(classificationFormatMap);
var formatMap = typeMap.ClassificationFormatMapService.GetClassificationFormatMap("tooltip");
result.SetDefaultTextProperties(formatMap);
var textBlock = new TextBlock { TextWrapping = TextWrapping.Wrap };
textBlock.SetDefaultTextProperties(formatMap);
textBlock.Inlines.AddRange(inlines);
result.Inlines.AddRange(parts.ToInlines(typeMap));
return textBlock;
}
public static IList<ClassificationSpan> ToClassificationSpans(
......
......@@ -14,7 +14,9 @@ internal class ViewHostingControl : ContentControl
private readonly Func<ITextBuffer, IWpfTextView> _createView;
private readonly Func<ITextBuffer> _createBuffer;
public ViewHostingControl(Func<ITextBuffer, IWpfTextView> createView, Func<ITextBuffer> createBuffer)
public ViewHostingControl(
Func<ITextBuffer, IWpfTextView> createView,
Func<ITextBuffer> createBuffer)
{
_createView = createView;
_createBuffer = createBuffer;
......
......@@ -27,7 +27,7 @@ public DocumentDefinitionLocation(DocumentLocation location)
public override ImmutableArray<TaggedText> OriginationParts =>
ImmutableArray.Create(new TaggedText(TextTags.Text, Location.Document.Project.Name));
public override bool CanNavigateTo() => Location.CanNavigateTo();
public override bool CanNavigateTo() => true;
public override bool TryNavigateTo() => Location.TryNavigateTo();
}
}
......
......@@ -48,13 +48,6 @@ public override int GetHashCode()
this.SourceSpan.GetHashCode());
}
public bool CanNavigateTo()
{
var workspace = Document.Project.Solution.Workspace;
var service = workspace.Services.GetService<IDocumentNavigationService>();
return service.CanNavigateToPosition(workspace, Document.Id, SourceSpan.Start);
}
public bool TryNavigateTo()
{
var workspace = Document.Project.Solution.Workspace;
......
// 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.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
......@@ -11,7 +10,6 @@
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.FindReferences
......@@ -174,16 +172,13 @@ internal static class DefinitionItemExtensions
{
result.Add(DefinitionLocation.CreateSymbolLocation(solution, definition));
}
else if (location.IsInSource)
else if (location.IsVisibleSourceLocation())
{
var document = solution.GetDocument(location.SourceTree);
if (document != null)
{
var documentLocation = new DocumentLocation(document, location.SourceSpan);
if (documentLocation.CanNavigateTo())
{
result.Add(DefinitionLocation.CreateDocumentLocation(documentLocation));
}
result.Add(DefinitionLocation.CreateDocumentLocation(
new DocumentLocation(document, location.SourceSpan)));
}
}
}
......@@ -205,18 +200,15 @@ internal static class DefinitionItemExtensions
DefinitionItem definitionItem)
{
var location = referenceLocation.Location;
Debug.Assert(location.IsInSource);
var document = referenceLocation.Document;
var sourceSpan = location.SourceSpan;
var documentLocation = new DocumentLocation(document, sourceSpan);
if (!documentLocation.CanNavigateTo())
Debug.Assert(location.IsInSource);
if (!location.IsVisibleSourceLocation())
{
return null;
}
return new SourceReferenceItem(definitionItem, documentLocation);
return new SourceReferenceItem(definitionItem,
new DocumentLocation(referenceLocation.Document, location.SourceSpan));
}
private static readonly SymbolDisplayFormat s_definitionDisplayFormat =
......
using System;
using System.Collections.Immutable;
using System.Windows;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor;
......@@ -11,6 +10,13 @@
using Microsoft.VisualStudio.Shell.TableControl;
using Microsoft.VisualStudio.Shell.TableManager;
using Microsoft.VisualStudio.Text;
using System.IO;
using System.Windows.Media;
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem;
using Microsoft.VisualStudio.LanguageServices.Implementation.Extensions;
using Roslyn.Utilities;
using System.Collections;
using System.Collections.Generic;
namespace Microsoft.VisualStudio.LanguageServices.FindReferences
{
......@@ -19,30 +25,36 @@ internal partial class StreamingFindReferencesPresenter
private class ReferenceEntry
{
private readonly StreamingFindReferencesPresenter _presenter;
private readonly VisualStudioWorkspaceImpl _workspace;
private readonly RoslynDefinitionBucket _definitionBucket;
private readonly SourceReferenceItem _sourceReferenceItem;
private readonly object _boxedProjectGuid;
private readonly SourceText _sourceText;
private readonly ImmutableArray<TaggedText> _taggedParts;
private readonly TaggedTextAndHighlightSpan _taggedLineParts;
private readonly TaggedTextAndHighlightSpan _taggedRegionParts;
public ReferenceEntry(
StreamingFindReferencesPresenter presenter,
VisualStudioWorkspaceImpl workspace,
RoslynDefinitionBucket definitionBucket,
SourceReferenceItem sourceReferenceItem,
Guid projectGuid,
SourceText sourceText,
ImmutableArray<TaggedText> taggedParts)
TaggedTextAndHighlightSpan taggedLineParts,
TaggedTextAndHighlightSpan taggedRegionParts)
{
_presenter = presenter;
_workspace = workspace;
_definitionBucket = definitionBucket;
_sourceReferenceItem = sourceReferenceItem;
_boxedProjectGuid = projectGuid;
_sourceText = sourceText;
_taggedParts = taggedParts;
_taggedLineParts = taggedLineParts;
_taggedRegionParts = taggedRegionParts;
}
public bool TryGetValue(string keyName, out object content)
......@@ -51,6 +63,31 @@ public bool TryGetValue(string keyName, out object content)
return content != null;
}
//internal bool TryCreateColumnContent(string columnName, out FrameworkElement element)
//{
// if (columnName == StandardTableKeyNames2.TextInlines)
// {
// var backgroundBrush = _presenter._formatMapService.GetEditorFormatMap("tooltip").GetProperties("MarkerFormatDefinition/HighlightedReference")["BackgroundColor"];
// var textBlock = _taggedParts.TaggedText.ToTextBlock(_presenter._typeMap,
// (run, taggedText, position) =>
// {
// if (position == _taggedParts.HighlightSpan.Start)
// {
// run.SetValue(
// System.Windows.Documents.TextElement.BackgroundProperty,
// backgroundBrush);
// }
// });
// element = textBlock;
// return true;
// }
// element = null;
// return false;
//}
private DocumentLocation Location => _sourceReferenceItem.Location;
private Document Document => Location.Document;
private TextSpan SourceSpan => Location.SourceSpan;
......@@ -60,7 +97,18 @@ private object GetValue(string keyName)
switch (keyName)
{
case StandardTableKeyNames.DocumentName:
return Document.FilePath;
var projectFilePath = Document.Project.FilePath;
var documentPath = Document.FilePath;
var projectDirectory = Path.GetDirectoryName(projectFilePath);
if (documentPath.StartsWith(projectDirectory, StringComparison.OrdinalIgnoreCase))
{
documentPath = documentPath.Substring(projectDirectory.Length);
documentPath = documentPath.TrimStart('\\', '/');
}
return documentPath;
// return Document.FilePath;
case StandardTableKeyNames.Line:
return _sourceText.Lines.GetLinePosition(SourceSpan.Start).Line;
case StandardTableKeyNames.Column:
......@@ -78,8 +126,8 @@ private object GetValue(string keyName)
// return GetEllisionBufferAroundReference();
return _sourceText.Lines.GetLineFromPosition(SourceSpan.Start).ToString().Trim();
//case StandardTableKeyNames2.TextInlines:
// return _taggedParts.ToTextBlock(_presenter._typeMap).Inlines;
case StandardTableKeyNames2.TextInlines:
return GetHighlightedInlines(_presenter, _taggedLineParts);
case StandardTableKeyNames2.DefinitionIcon:
return _definitionBucket.DefinitionItem.Tags.GetGlyph().GetImageMoniker();
......@@ -91,51 +139,112 @@ private object GetValue(string keyName)
return null;
}
private static IList<System.Windows.Documents.Inline> GetHighlightedInlines(
StreamingFindReferencesPresenter presenter,
TaggedTextAndHighlightSpan taggedTextAndHighlight,
string classificationFormatMap = null)
{
var properties = presenter._formatMapService
.GetEditorFormatMap("text")
.GetProperties("MarkerFormatDefinition/HighlightedReference");
var highlightBrush = properties["Background"] as Brush;
var lineParts = taggedTextAndHighlight.TaggedText;
var inlines = lineParts.ToInlines(
presenter._typeMap,
classificationFormatMap,
(run, taggedText, position) =>
{
if (highlightBrush != null)
{
if (position == taggedTextAndHighlight.HighlightSpan.Start)
{
run.SetValue(
System.Windows.Documents.TextElement.BackgroundProperty,
highlightBrush);
}
}
});
return inlines;
}
internal bool TryCreateToolTip(string columnName, out object toolTip)
{
toolTip = GetEllisionBufferAroundReference();
var highlightedInlines = GetHighlightedInlines(_presenter, _taggedRegionParts, "text");
var textBlock = highlightedInlines.ToTextBlock(_presenter._typeMap, "text");
TextOptions.SetTextFormattingMode(textBlock, TextFormattingMode.Ideal);
var transform = new ScaleTransform(0.75, 0.75);
transform.Freeze();
textBlock.LayoutTransform = transform;
toolTip = textBlock;
return true;
}
private FrameworkElement GetEllisionBufferAroundReference()
{
var snapshotSpan = GetSnapshotSpanAroundReference();
var snapshotSpanAndCloseAction = GetSnapshotSpanAroundReference();
if (snapshotSpanAndCloseAction == null)
{
return null;
}
var snapshotSpan = snapshotSpanAndCloseAction.Item1;
var closeAction = snapshotSpanAndCloseAction.Item2;
var content = new ElisionBufferDeferredContent(
snapshotSpan,
_presenter._projectionBufferFactoryService,
_presenter._editorOptionsFactoryService,
_presenter._textEditorFactoryService);
return content.Create();
var element = content.Create();
return element;
}
private SnapshotSpan GetSnapshotSpanAroundReference()
private Tuple<SnapshotSpan, Action> GetSnapshotSpanAroundReference()
{
var snapshot = GetTextSnapshot();
var snapshotAndCloseAction = GetTextSnapshotAndCloseAction();
var snapshot = snapshotAndCloseAction.Item1;
var closeAction = snapshotAndCloseAction.Item2;
var wholeSnapshotSpan = new TextSpan(0, snapshot.Length);
var finalSpan = this.SourceSpan.Intersection(wholeSnapshotSpan) ?? default(TextSpan);
var lines = _sourceText.Lines;
var lineNumber = lines.GetLineFromPosition(SourceSpan.Start).LineNumber;
var lineNumber = snapshot.GetLineNumberFromPosition(finalSpan.Start);
var firstLineNumber = Math.Max(0, lineNumber - 2);
var lastLineNumber = Math.Min(lines.Count - 1, lineNumber + 2);
var lastLineNumber = Math.Min(snapshot.LineCount - 1, lineNumber + 2);
return new SnapshotSpan(snapshot,
Span.FromBounds(lines[firstLineNumber].Start, lines[lastLineNumber].End));
var snapshotSpan = new SnapshotSpan(snapshot,
Span.FromBounds(
snapshot.GetLineFromLineNumber(firstLineNumber).Start,
snapshot.GetLineFromLineNumber(lastLineNumber).End));
return Tuple.Create(snapshotSpan, closeAction);
}
private ITextSnapshot GetTextSnapshot()
private Tuple<ITextSnapshot, Action> GetTextSnapshotAndCloseAction()
{
// Get the existing editor snapshot (if this is already open in an editor),
// otherwise create a new snapshot that we can display.
return _sourceText.FindCorrespondingEditorTextSnapshot() ?? CreateSnapshot();
var snapshot = _sourceText.FindCorrespondingEditorTextSnapshot();
if (snapshot != null)
{
return Tuple.Create(snapshot, (Action)null);
}
return OpenInvisibleEditorAndGetTextSnapshot();
}
private ITextSnapshot CreateSnapshot()
private Tuple<ITextSnapshot, Action> OpenInvisibleEditorAndGetTextSnapshot()
{
var contentTypeService = Document.GetLanguageService<IContentTypeLanguageService>();
var contentType = contentTypeService.GetDefaultContentType();
var textBuffer = _presenter._textBufferFactoryService.CreateTextBuffer(_sourceText.ToString(), contentType);
return textBuffer.CurrentSnapshot;
var editor = _workspace.OpenInvisibleEditor(this.Document.Id);
return Tuple.Create(
editor.TextBuffer.CurrentSnapshot,
(Action)(() => editor.Dispose()));
}
}
}
......
......@@ -48,18 +48,24 @@ private object GetValue(string key)
return DefinitionItem.DisplayParts.JoinText();
case StandardTableKeyNames2.TextInlines:
return DefinitionItem.DisplayParts.ToInlines(_presenter._typeMap);
var inlines = new List<Inline> { new Run(" ") };
inlines.AddRange(DefinitionItem.DisplayParts.ToInlines(_presenter._typeMap));
foreach (var inline in inlines)
{
inline.SetValue(TextElement.FontWeightProperty, FontWeights.Bold);
}
return inlines;
case StandardTableKeyNames2.DefinitionIcon:
return DefinitionItem.Tags.GetGlyph().GetImageMoniker();
//case StandardTableKeyNames2.TextInlines:
// // content of the bucket displayed as a rich text
// var inlines = new List<Inline>();
// inlines.Add(new Run("testing") { FontWeight = FontWeights.Bold });
// inlines.Add(new Run(": defined in "));
//case StandardTableKeyNames2.TextInlines:
// // content of the bucket displayed as a rich text
// var inlines = new List<Inline>();
// inlines.Add(new Run("testing") { FontWeight = FontWeights.Bold });
// inlines.Add(new Run(": defined in "));
// return inlines;
// return inlines;
}
return null;
......
......@@ -195,37 +195,55 @@ private async Task OnReferenceFoundAsync(SourceReferenceItem referenceItem)
return null;
}
var taggedText = await GetTaggedTextForReferenceAsync(document, referenceItem, cancellationToken).ConfigureAwait(false);
var sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
var referenceSpan = referenceItem.Location.SourceSpan;
var lineSpan = GetLineSpanForReference(sourceText, referenceSpan);
var regionSpan = GetRegionSpanForReference(sourceText, referenceSpan);
var taggedLineParts = await GetTaggedTextForReferenceAsync(document, referenceSpan, lineSpan, cancellationToken).ConfigureAwait(false);
var taggedRegionParts = await GetTaggedTextForReferenceAsync(document, referenceSpan, regionSpan, cancellationToken).ConfigureAwait(false);
return new ReferenceEntry(
_presenter, definitionBucket, referenceItem,
projectGuid.Value, sourceText, taggedText);
_presenter, workspace, definitionBucket, referenceItem,
projectGuid.Value, sourceText, taggedLineParts, taggedRegionParts);
}
private Task<ImmutableArray<TaggedText>> GetTaggedTextForDefinitionAsync(
DefinitionItem item)
private TextSpan GetLineSpanForReference(SourceText sourceText, TextSpan referenceSpan)
{
return Task.FromResult(item.DisplayParts);
var sourceLine = sourceText.Lines.GetLineFromPosition(referenceSpan.Start);
var firstNonWhitespacePosition = sourceLine.GetFirstNonWhitespacePosition().Value;
return TextSpan.FromBounds(firstNonWhitespacePosition, sourceLine.End);
}
private async Task<ImmutableArray<TaggedText>> GetTaggedTextForReferenceAsync(
Document document, SourceReferenceItem item, CancellationToken cancellationToken)
private TextSpan GetRegionSpanForReference(SourceText sourceText, TextSpan referenceSpan)
{
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
var lineNumber = sourceText.Lines.GetLineFromPosition(referenceSpan.Start).LineNumber;
var referenceSpan = item.Location.SourceSpan;
var sourceLine = sourceText.Lines.GetLineFromPosition(referenceSpan.Start);
var firstLineNumber = Math.Max(0, lineNumber - 2);
var lastLineNumber = Math.Min(sourceText.Lines.Count - 1, lineNumber + 2);
var firstNonWhitespacePosition = sourceLine.GetFirstNonWhitespacePosition().Value;
var span = TextSpan.FromBounds(firstNonWhitespacePosition, sourceLine.End);
return TextSpan.FromBounds(
sourceText.Lines[firstLineNumber].Start,
sourceText.Lines[lastLineNumber].End);
}
private async Task<TaggedTextAndHighlightSpan> GetTaggedTextForReferenceAsync(
Document document, TextSpan referenceSpan, TextSpan widenedSpan, CancellationToken cancellationToken)
{
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
// TODO: highlight the actual reference span in some way.
var classifiedLineParts = await Classifier.GetClassifiedSymbolDisplayPartsAsync(
semanticModel, span, document.Project.Solution.Workspace, cancellationToken).ConfigureAwait(false);
semanticModel, widenedSpan, document.Project.Solution.Workspace, cancellationToken).ConfigureAwait(false);
var taggedText = classifiedLineParts.ToTaggedText();
var highlightSpan = new TextSpan(
start: referenceSpan.Start - widenedSpan.Start,
length: referenceSpan.Length);
return classifiedLineParts.ToTaggedText();
return new TaggedTextAndHighlightSpan(taggedText, highlightSpan);
}
private RoslynDefinitionBucket GetOrCreateDefinitionBucket(DefinitionItem definition)
......
using System.Collections.Immutable;
using System.Windows;
using Microsoft.VisualStudio.Shell.TableControl;
using Microsoft.VisualStudio.Shell.TableManager;
......@@ -38,6 +39,12 @@ public override bool TryCreateToolTip(int index, string columnName, out object t
{
return this._referenceEntries[index].TryCreateToolTip(columnName, out toolTip);
}
//public override bool TryCreateColumnContent(
// int index, string columnName, bool singleColumnView, out FrameworkElement content)
//{
// return this._referenceEntries[index].TryCreateColumnContent(columnName, out content);
//}
}
}
}
\ No newline at end of file
......@@ -9,6 +9,7 @@
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Projection;
using Microsoft.VisualStudio.Text.Classification;
namespace Microsoft.VisualStudio.LanguageServices.FindReferences
{
......@@ -31,6 +32,7 @@ internal partial class StreamingFindReferencesPresenter :
private readonly ITextEditorFactoryService _textEditorFactoryService;
private readonly ClassificationTypeMap _typeMap;
private readonly IEditorFormatMapService _formatMapService;
private readonly IFindAllReferencesService _vsFindAllReferencesService;
[ImportingConstructor]
......@@ -41,6 +43,7 @@ internal partial class StreamingFindReferencesPresenter :
IEditorOptionsFactoryService editorOptionsFactoryService,
ITextEditorFactoryService textEditorFactoryService,
ClassificationTypeMap typeMap,
IEditorFormatMapService formatMapService,
[ImportMany] IEnumerable<Lazy<IAsynchronousOperationListener, FeatureMetadata>> asyncListeners)
{
_serviceProvider = serviceProvider;
......@@ -49,6 +52,7 @@ internal partial class StreamingFindReferencesPresenter :
_editorOptionsFactoryService = editorOptionsFactoryService;
_textEditorFactoryService = textEditorFactoryService;
_typeMap = typeMap;
_formatMapService = formatMapService;
_asyncListener = new AggregateAsynchronousOperationListener(
asyncListeners, FeatureAttribute.ReferenceHighlighting);
......
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.VisualStudio.LanguageServices.FindReferences
{
internal struct TaggedTextAndHighlightSpan
{
public readonly ImmutableArray<TaggedText> TaggedText;
public readonly TextSpan HighlightSpan;
public TaggedTextAndHighlightSpan(ImmutableArray<TaggedText> taggedText, TextSpan highlightSpan)
{
TaggedText = taggedText;
HighlightSpan = highlightSpan;
}
}
}
......@@ -32,6 +32,7 @@
<Compile Include="FindReferences\StreamingFindReferencesPresenter.TableEntriesSnapshot.cs" />
<Compile Include="FindReferences\StreamingFindReferencesPresenter.ReferenceEntry.cs" />
<Compile Include="FindReferences\FindReferencesTableControlEventProcessorProvider.cs" />
<Compile Include="FindReferences\TaggedTextAndHighlightSpan.cs" />
</ItemGroup>
<ItemGroup Label="Project References">
<ProjectReference Include="..\..\..\Compilers\Core\Portable\CodeAnalysis.csproj">
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册