提交 257c9eba 编写于 作者: C CyrusNajmabadi 提交者: GitHub

Merge pull request #15118 from CyrusNajmabadi/generatedCode

Share 'generated-code' logic between the compiler and IDE.
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
</Content> </Content>
<Compile Include="DiagnosticAnalyzer\AnalyzerManager.AnalyzerExecutionContext.cs" /> <Compile Include="DiagnosticAnalyzer\AnalyzerManager.AnalyzerExecutionContext.cs" />
<Compile Include="InternalUtilities\CommandLineUtilities.cs" /> <Compile Include="InternalUtilities\CommandLineUtilities.cs" />
<Compile Include="InternalUtilities\GeneratedCodeUtilities.cs" />
<Compile Include="InternalUtilities\NoThrowStreamDisposer.cs" /> <Compile Include="InternalUtilities\NoThrowStreamDisposer.cs" />
<Compile Include="InternalUtilities\OrderedMultiDictionary.cs" /> <Compile Include="InternalUtilities\OrderedMultiDictionary.cs" />
<Compile Include="InternalUtilities\PlatformInformation.cs" /> <Compile Include="InternalUtilities\PlatformInformation.cs" />
...@@ -86,7 +87,6 @@ ...@@ -86,7 +87,6 @@
<Compile Include="DiagnosticAnalyzer\SourceTextValueProvider.cs" /> <Compile Include="DiagnosticAnalyzer\SourceTextValueProvider.cs" />
<Compile Include="DiagnosticAnalyzer\CompilationAnalysisValueProviderFactory.cs" /> <Compile Include="DiagnosticAnalyzer\CompilationAnalysisValueProviderFactory.cs" />
<Compile Include="DiagnosticAnalyzer\CompilationAnalysisValueProvider.cs" /> <Compile Include="DiagnosticAnalyzer\CompilationAnalysisValueProvider.cs" />
<Compile Include="DiagnosticAnalyzer\AnalyzerDriver.GeneratedCodeUtilities.cs" />
<Compile Include="DiagnosticAnalyzer\AnalyzerDriver.CompilationData.cs" /> <Compile Include="DiagnosticAnalyzer\AnalyzerDriver.CompilationData.cs" />
<Compile Include="DiagnosticAnalyzer\AnalysisContextInfo.cs" /> <Compile Include="DiagnosticAnalyzer\AnalysisContextInfo.cs" />
<Compile Include="DiagnosticAnalyzer\AnalysisValueProvider.cs" /> <Compile Include="DiagnosticAnalyzer\AnalysisValueProvider.cs" />
......
...@@ -4,17 +4,16 @@ ...@@ -4,17 +4,16 @@
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using Roslyn.Utilities; using Microsoft.CodeAnalysis;
namespace Microsoft.CodeAnalysis.Diagnostics namespace Roslyn.Utilities
{ {
internal abstract partial class AnalyzerDriver : IDisposable internal static class GeneratedCodeUtilities
{
private static class GeneratedCodeUtilities
{ {
private static readonly string[] s_autoGeneratedStrings = new[] { "<autogenerated", "<auto-generated" }; private static readonly string[] s_autoGeneratedStrings = new[] { "<autogenerated", "<auto-generated" };
internal static bool IsGeneratedSymbolWithGeneratedCodeAttribute(ISymbol symbol, INamedTypeSymbol generatedCodeAttribute) internal static bool IsGeneratedSymbolWithGeneratedCodeAttribute(
ISymbol symbol, INamedTypeSymbol generatedCodeAttribute)
{ {
Debug.Assert(symbol != null); Debug.Assert(symbol != null);
Debug.Assert(generatedCodeAttribute != null); Debug.Assert(generatedCodeAttribute != null);
...@@ -34,53 +33,42 @@ internal static bool IsGeneratedSymbolWithGeneratedCodeAttribute(ISymbol symbol, ...@@ -34,53 +33,42 @@ internal static bool IsGeneratedSymbolWithGeneratedCodeAttribute(ISymbol symbol,
return symbol.ContainingSymbol != null && IsGeneratedSymbolWithGeneratedCodeAttribute(symbol.ContainingSymbol, generatedCodeAttribute); return symbol.ContainingSymbol != null && IsGeneratedSymbolWithGeneratedCodeAttribute(symbol.ContainingSymbol, generatedCodeAttribute);
} }
internal static bool IsGeneratedCode(SyntaxTree tree, Func<SyntaxTrivia, bool> isComment, CancellationToken cancellationToken) internal static bool IsGeneratedCode(
SyntaxTree tree, Func<SyntaxTrivia, bool> isComment, CancellationToken cancellationToken)
{ {
if (IsGeneratedCodeFile(tree.FilePath)) return IsGeneratedCodeFile(tree.FilePath) ||
{ BeginsWithAutoGeneratedComment(tree, isComment, cancellationToken);
return true;
}
if (BeginsWithAutoGeneratedComment(tree, isComment, cancellationToken))
{
return true;
}
return false;
} }
private static bool IsGeneratedCodeFile(string filePath) private static bool IsGeneratedCodeFile(string filePath)
{ {
if (string.IsNullOrEmpty(filePath)) if (!string.IsNullOrEmpty(filePath))
{ {
return false; var fileName = PathUtilities.GetFileName(filePath);
} if (fileName.StartsWith("TemporaryGeneratedFile_", StringComparison.OrdinalIgnoreCase))
{
var fileName = PathUtilities.GetFileName(filePath); return true;
if (fileName.StartsWith("TemporaryGeneratedFile_", StringComparison.OrdinalIgnoreCase)) }
{
return true;
}
var extension = PathUtilities.GetExtension(fileName);
if (string.IsNullOrEmpty(extension))
{
return false;
}
var fileNameWithoutExtension = PathUtilities.GetFileName(filePath, includeExtension: false); var extension = PathUtilities.GetExtension(fileName);
if (fileNameWithoutExtension.EndsWith(".designer", StringComparison.OrdinalIgnoreCase) || if (!string.IsNullOrEmpty(extension))
fileNameWithoutExtension.EndsWith(".generated", StringComparison.OrdinalIgnoreCase) || {
fileNameWithoutExtension.EndsWith(".g", StringComparison.OrdinalIgnoreCase) || var fileNameWithoutExtension = PathUtilities.GetFileName(filePath, includeExtension: false);
fileNameWithoutExtension.EndsWith(".g.i", StringComparison.OrdinalIgnoreCase)) if (fileNameWithoutExtension.EndsWith(".designer", StringComparison.OrdinalIgnoreCase) ||
{ fileNameWithoutExtension.EndsWith(".generated", StringComparison.OrdinalIgnoreCase) ||
return true; fileNameWithoutExtension.EndsWith(".g", StringComparison.OrdinalIgnoreCase) ||
fileNameWithoutExtension.EndsWith(".g.i", StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
} }
return false; return false;
} }
private static bool BeginsWithAutoGeneratedComment(SyntaxTree tree, Func<SyntaxTrivia, bool> isComment, CancellationToken cancellationToken) private static bool BeginsWithAutoGeneratedComment(
SyntaxTree tree, Func<SyntaxTrivia, bool> isComment, CancellationToken cancellationToken)
{ {
var root = tree.GetRoot(cancellationToken); var root = tree.GetRoot(cancellationToken);
if (root.HasLeadingTrivia) if (root.HasLeadingTrivia)
...@@ -110,5 +98,4 @@ private static bool BeginsWithAutoGeneratedComment(SyntaxTree tree, Func<SyntaxT ...@@ -110,5 +98,4 @@ private static bool BeginsWithAutoGeneratedComment(SyntaxTree tree, Func<SyntaxT
return false; return false;
} }
} }
} }
} \ No newline at end of file
...@@ -20,7 +20,8 @@ internal abstract class AbstractNavigationBarItemService : INavigationBarItemSer ...@@ -20,7 +20,8 @@ internal abstract class AbstractNavigationBarItemService : INavigationBarItemSer
public abstract void NavigateToItem(Document document, NavigationBarItem item, ITextView textView, CancellationToken cancellationToken); public abstract void NavigateToItem(Document document, NavigationBarItem item, ITextView textView, CancellationToken cancellationToken);
public void NavigateToSymbolItem(Document document, NavigationBarSymbolItem item, CancellationToken cancellationToken) public void NavigateToSymbolItem(
Document document, NavigationBarSymbolItem item, CancellationToken cancellationToken)
{ {
var symbolNavigationService = document.Project.Solution.Workspace.Services.GetService<ISymbolNavigationService>(); var symbolNavigationService = document.Project.Solution.Workspace.Services.GetService<ISymbolNavigationService>();
...@@ -31,7 +32,7 @@ public void NavigateToSymbolItem(Document document, NavigationBarSymbolItem item ...@@ -31,7 +32,7 @@ public void NavigateToSymbolItem(Document document, NavigationBarSymbolItem item
if (symbol != null && if (symbol != null &&
!(symbol is ITypeSymbol) && !(symbol is ITypeSymbol) &&
!symbol.IsConstructor() && !symbol.IsConstructor() &&
symbolNavigationService.TrySymbolNavigationNotify(symbol, document.Project.Solution)) symbolNavigationService.TrySymbolNavigationNotify(symbol, document.Project.Solution, cancellationToken))
{ {
return; return;
} }
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Editor.FindUsages; using Microsoft.CodeAnalysis.Editor.FindUsages;
using Microsoft.CodeAnalysis.Editor.Host; using Microsoft.CodeAnalysis.Editor.Host;
...@@ -59,7 +60,7 @@ public bool TryFindReferences(Document document, int position, IWaitContext wait ...@@ -59,7 +60,7 @@ public bool TryFindReferences(Document document, int position, IWaitContext wait
var cancellationToken = waitContext.CancellationToken; var cancellationToken = waitContext.CancellationToken;
var result = this.FindReferencedSymbolsAsync(document, position, waitContext).WaitAndGetResult(cancellationToken); var result = this.FindReferencedSymbolsAsync(document, position, waitContext).WaitAndGetResult(cancellationToken);
return TryDisplayReferences(result); return TryDisplayReferences(result, cancellationToken);
} }
private bool TryDisplayReferences(IEnumerable<INavigableItem> result) private bool TryDisplayReferences(IEnumerable<INavigableItem> result)
...@@ -77,14 +78,16 @@ private bool TryDisplayReferences(IEnumerable<INavigableItem> result) ...@@ -77,14 +78,16 @@ private bool TryDisplayReferences(IEnumerable<INavigableItem> result)
return false; return false;
} }
private bool TryDisplayReferences(Tuple<IEnumerable<ReferencedSymbol>, Solution> result) private bool TryDisplayReferences(
Tuple<IEnumerable<ReferencedSymbol>, Solution> result,
CancellationToken cancellationToken)
{ {
if (result != null && result.Item1 != null) if (result != null && result.Item1 != null)
{ {
var solution = result.Item2; var solution = result.Item2;
var factory = solution.Workspace.Services.GetService<IDefinitionsAndReferencesFactory>(); var factory = solution.Workspace.Services.GetService<IDefinitionsAndReferencesFactory>();
var definitionsAndReferences = factory.CreateDefinitionsAndReferences( var definitionsAndReferences = factory.CreateDefinitionsAndReferences(
solution, result.Item1, includeHiddenLocations: false); solution, result.Item1, includeHiddenLocations: false, cancellationToken: cancellationToken);
foreach (var presenter in _referenceSymbolPresenters) foreach (var presenter in _referenceSymbolPresenters)
{ {
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.FindUsages; using Microsoft.CodeAnalysis.FindUsages;
...@@ -85,12 +86,13 @@ public async Task OnReferenceFoundAsync(SymbolAndProjectId definition, Reference ...@@ -85,12 +86,13 @@ public async Task OnReferenceFoundAsync(SymbolAndProjectId definition, Reference
} }
} }
public async Task CallThirdPartyExtensionsAsync() public async Task CallThirdPartyExtensionsAsync(CancellationToken cancellationToken)
{ {
var factory = _solution.Workspace.Services.GetService<IDefinitionsAndReferencesFactory>(); var factory = _solution.Workspace.Services.GetService<IDefinitionsAndReferencesFactory>();
foreach (var definition in _definitionToItem.Keys) foreach (var definition in _definitionToItem.Keys)
{ {
var item = factory.GetThirdPartyDefinitionItem(_solution, definition); var item = factory.GetThirdPartyDefinitionItem(
_solution, definition, cancellationToken);
if (item != null) if (item != null)
{ {
// ConfigureAwait(true) because we want to come back on the // ConfigureAwait(true) because we want to come back on the
......
...@@ -56,7 +56,8 @@ public async Task FindImplementationsAsync(Document document, int position, IFin ...@@ -56,7 +56,8 @@ public async Task FindImplementationsAsync(Document document, int position, IFin
// After the FAR engine is done call into any third party extensions to see // After the FAR engine is done call into any third party extensions to see
// if they want to add results. // if they want to add results.
await findReferencesProgress.CallThirdPartyExtensionsAsync().ConfigureAwait(true); await findReferencesProgress.CallThirdPartyExtensionsAsync(
context.CancellationToken).ConfigureAwait(true);
} }
private async Task<ProgressAdapter> FindReferencesWorkerAsync( private async Task<ProgressAdapter> FindReferencesWorkerAsync(
......
...@@ -50,13 +50,14 @@ private async Task<ISymbol> FindSymbolAsync(Document document, int position, Can ...@@ -50,13 +50,14 @@ private async Task<ISymbol> FindSymbolAsync(Document document, int position, Can
return FindRelatedExplicitlyDeclaredSymbol(symbol, semanticModel.Compilation); return FindRelatedExplicitlyDeclaredSymbol(symbol, semanticModel.Compilation);
} }
public async Task<IEnumerable<INavigableItem>> FindDefinitionsAsync(Document document, int position, CancellationToken cancellationToken) public async Task<IEnumerable<INavigableItem>> FindDefinitionsAsync(
Document document, int position, CancellationToken cancellationToken)
{ {
var symbol = await FindSymbolAsync(document, position, cancellationToken).ConfigureAwait(false); var symbol = await FindSymbolAsync(document, position, cancellationToken).ConfigureAwait(false);
// Try to compute source definitions from symbol. // Try to compute source definitions from symbol.
var items = symbol != null var items = symbol != null
? NavigableItemFactory.GetItemsFromPreferredSourceLocations(document.Project.Solution, symbol, displayTaggedParts: null) ? NavigableItemFactory.GetItemsFromPreferredSourceLocations(document.Project.Solution, symbol, displayTaggedParts: null, cancellationToken: cancellationToken)
: null; : null;
// realize the list here so that the consumer await'ing the result doesn't lazily cause // realize the list here so that the consumer await'ing the result doesn't lazily cause
......
...@@ -40,10 +40,15 @@ internal static class GoToDefinitionHelpers ...@@ -40,10 +40,15 @@ internal static class GoToDefinitionHelpers
// We can't go to the definition of the alias, so use the target type. // We can't go to the definition of the alias, so use the target type.
var solution = project.Solution; var solution = project.Solution;
if (symbol is IAliasSymbol && if (symbol is IAliasSymbol)
NavigableItemFactory.GetPreferredSourceLocations(solution, symbol).All(l => project.Solution.GetDocument(l.SourceTree) == null))
{ {
symbol = ((IAliasSymbol)symbol).Target; var sourceLocations = NavigableItemFactory.GetPreferredSourceLocations(
solution, symbol, cancellationToken);
if (sourceLocations.All(l => project.Solution.GetDocument(l.SourceTree) == null))
{
symbol = ((IAliasSymbol)symbol).Target;
}
} }
var definition = SymbolFinder.FindSourceDefinitionAsync(symbol, solution, cancellationToken).WaitAndGetResult(cancellationToken); var definition = SymbolFinder.FindSourceDefinitionAsync(symbol, solution, cancellationToken).WaitAndGetResult(cancellationToken);
...@@ -52,10 +57,10 @@ internal static class GoToDefinitionHelpers ...@@ -52,10 +57,10 @@ internal static class GoToDefinitionHelpers
symbol = definition ?? symbol; symbol = definition ?? symbol;
var definitions = ArrayBuilder<DefinitionItem>.GetInstance(); var definitions = ArrayBuilder<DefinitionItem>.GetInstance();
if (thirdPartyNavigationAllowed ) if (thirdPartyNavigationAllowed)
{ {
var factory = solution.Workspace.Services.GetService<IDefinitionsAndReferencesFactory>(); var factory = solution.Workspace.Services.GetService<IDefinitionsAndReferencesFactory>();
var thirdPartyItem = factory?.GetThirdPartyDefinitionItem(solution, symbol); var thirdPartyItem = factory?.GetThirdPartyDefinitionItem(solution, symbol, cancellationToken);
definitions.AddIfNotNull(thirdPartyItem); definitions.AddIfNotNull(thirdPartyItem);
} }
...@@ -92,12 +97,13 @@ internal static class GoToDefinitionHelpers ...@@ -92,12 +97,13 @@ internal static class GoToDefinitionHelpers
} }
} }
private static bool TryThirdPartyNavigation(ISymbol symbol, Solution solution) private static bool TryThirdPartyNavigation(
ISymbol symbol, Solution solution, CancellationToken cancellationToken)
{ {
var symbolNavigationService = solution.Workspace.Services.GetService<ISymbolNavigationService>(); var symbolNavigationService = solution.Workspace.Services.GetService<ISymbolNavigationService>();
// Notify of navigation so third parties can intercept the navigation // Notify of navigation so third parties can intercept the navigation
return symbolNavigationService.TrySymbolNavigationNotify(symbol, solution); return symbolNavigationService.TrySymbolNavigationNotify(symbol, solution, cancellationToken);
} }
} }
} }
\ No newline at end of file
...@@ -25,7 +25,10 @@ private PeekableItemFactory(IMetadataAsSourceFileService metadataAsSourceFileSer ...@@ -25,7 +25,10 @@ private PeekableItemFactory(IMetadataAsSourceFileService metadataAsSourceFileSer
_metadataAsSourceFileService = metadataAsSourceFileService; _metadataAsSourceFileService = metadataAsSourceFileService;
} }
public async Task<IEnumerable<IPeekableItem>> GetPeekableItemsAsync(ISymbol symbol, Project project, IPeekResultFactory peekResultFactory, CancellationToken cancellationToken) public async Task<IEnumerable<IPeekableItem>> GetPeekableItemsAsync(
ISymbol symbol, Project project,
IPeekResultFactory peekResultFactory,
CancellationToken cancellationToken)
{ {
if (symbol == null) if (symbol == null)
{ {
...@@ -57,7 +60,9 @@ public async Task<IEnumerable<IPeekableItem>> GetPeekableItemsAsync(ISymbol symb ...@@ -57,7 +60,9 @@ public async Task<IEnumerable<IPeekableItem>> GetPeekableItemsAsync(ISymbol symb
var symbolNavigationService = solution.Workspace.Services.GetService<ISymbolNavigationService>(); var symbolNavigationService = solution.Workspace.Services.GetService<ISymbolNavigationService>();
if (symbolNavigationService.WouldNavigateToSymbol(symbol, solution, out var filePath, out var lineNumber, out var charOffset)) if (symbolNavigationService.WouldNavigateToSymbol(
symbol, solution, cancellationToken,
out var filePath, out var lineNumber, out var charOffset))
{ {
var position = new LinePosition(lineNumber, charOffset); var position = new LinePosition(lineNumber, charOffset);
results.Add(new ExternalFilePeekableItem(new FileLinePositionSpan(filePath, position, position), PredefinedPeekRelationships.Definitions, peekResultFactory)); results.Add(new ExternalFilePeekableItem(new FileLinePositionSpan(filePath, position, position), PredefinedPeekRelationships.Definitions, peekResultFactory));
......
...@@ -13,7 +13,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Utilities.GoToHelpers ...@@ -13,7 +13,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Utilities.GoToHelpers
Public ReadOnly Catalog As ComposableCatalog = TestExportProvider.MinimumCatalogWithCSharpAndVisualBasic.WithParts( Public ReadOnly Catalog As ComposableCatalog = TestExportProvider.MinimumCatalogWithCSharpAndVisualBasic.WithParts(
GetType(MockDocumentNavigationServiceFactory), GetType(MockDocumentNavigationServiceFactory),
GetType(DefaultSymbolNavigationServiceFactory), GetType(DefaultSymbolNavigationServiceFactory),
GetType(GeneratedCodeRecognitionServiceFactory)) GetType(GeneratedCodeRecognitionService))
Public ReadOnly ExportProvider As ExportProvider = MinimalTestExportProvider.CreateExportProvider(Catalog) Public ReadOnly ExportProvider As ExportProvider = MinimalTestExportProvider.CreateExportProvider(Catalog)
......
...@@ -45,14 +45,19 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Utilities ...@@ -45,14 +45,19 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Utilities
Return True Return True
End Function End Function
Public Function TrySymbolNavigationNotify(symbol As ISymbol, solution As Solution) As Boolean Implements ISymbolNavigationService.TrySymbolNavigationNotify Public Function TrySymbolNavigationNotify(symbol As ISymbol,
solution As Solution,
cancellationToken As CancellationToken) As Boolean Implements ISymbolNavigationService.TrySymbolNavigationNotify
Me.TrySymbolNavigationNotifyProvidedSymbol = symbol Me.TrySymbolNavigationNotifyProvidedSymbol = symbol
Me.TrySymbolNavigationNotifyProvidedSolution = solution Me.TrySymbolNavigationNotifyProvidedSolution = solution
Return TrySymbolNavigationNotifyReturnValue Return TrySymbolNavigationNotifyReturnValue
End Function End Function
Public Function WouldNavigateToSymbol(symbol As ISymbol, solution As Solution, ByRef filePath As String, ByRef lineNumber As Integer, ByRef charOffset As Integer) As Boolean Implements ISymbolNavigationService.WouldNavigateToSymbol Public Function WouldNavigateToSymbol(symbol As ISymbol,
solution As Solution,
cancellationToken As CancellationToken,
ByRef filePath As String, ByRef lineNumber As Integer, ByRef charOffset As Integer) As Boolean Implements ISymbolNavigationService.WouldNavigateToSymbol
Me.WouldNavigateToSymbolProvidedSymbol = symbol Me.WouldNavigateToSymbolProvidedSymbol = symbol
Me.WouldNavigateToSymbolProvidedSolution = solution Me.WouldNavigateToSymbolProvidedSolution = solution
......
...@@ -23,7 +23,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte ...@@ -23,7 +23,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte
return; return;
} }
if (document.IsGeneratedCode()) if (document.IsGeneratedCode(cancellationToken))
{ {
return; return;
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
using System.Composition; using System.Composition;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.Completion; using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Host;
...@@ -17,16 +18,19 @@ namespace Microsoft.CodeAnalysis.FindUsages ...@@ -17,16 +18,19 @@ namespace Microsoft.CodeAnalysis.FindUsages
internal interface IDefinitionsAndReferencesFactory : IWorkspaceService internal interface IDefinitionsAndReferencesFactory : IWorkspaceService
{ {
DefinitionsAndReferences CreateDefinitionsAndReferences( DefinitionsAndReferences CreateDefinitionsAndReferences(
Solution solution, IEnumerable<ReferencedSymbol> referencedSymbols, bool includeHiddenLocations); Solution solution, IEnumerable<ReferencedSymbol> referencedSymbols,
bool includeHiddenLocations, CancellationToken cancellationToken);
DefinitionItem GetThirdPartyDefinitionItem(Solution solution, ISymbol definition); DefinitionItem GetThirdPartyDefinitionItem(
Solution solution, ISymbol definition, CancellationToken cancellationToken);
} }
[ExportWorkspaceService(typeof(IDefinitionsAndReferencesFactory)), Shared] [ExportWorkspaceService(typeof(IDefinitionsAndReferencesFactory)), Shared]
internal class DefaultDefinitionsAndReferencesFactory : IDefinitionsAndReferencesFactory internal class DefaultDefinitionsAndReferencesFactory : IDefinitionsAndReferencesFactory
{ {
public DefinitionsAndReferences CreateDefinitionsAndReferences( public DefinitionsAndReferences CreateDefinitionsAndReferences(
Solution solution, IEnumerable<ReferencedSymbol> referencedSymbols, bool includeHiddenLocations) Solution solution, IEnumerable<ReferencedSymbol> referencedSymbols,
bool includeHiddenLocations, CancellationToken cancellationToken)
{ {
var definitions = ArrayBuilder<DefinitionItem>.GetInstance(); var definitions = ArrayBuilder<DefinitionItem>.GetInstance();
var references = ArrayBuilder<SourceReferenceItem>.GetInstance(); var references = ArrayBuilder<SourceReferenceItem>.GetInstance();
...@@ -40,7 +44,7 @@ internal class DefaultDefinitionsAndReferencesFactory : IDefinitionsAndReference ...@@ -40,7 +44,7 @@ internal class DefaultDefinitionsAndReferencesFactory : IDefinitionsAndReference
{ {
ProcessReferencedSymbol( ProcessReferencedSymbol(
solution, referencedSymbol, definitions, references, solution, referencedSymbol, definitions, references,
includeHiddenLocations, uniqueLocations); includeHiddenLocations, uniqueLocations,cancellationToken);
} }
return new DefinitionsAndReferences( return new DefinitionsAndReferences(
...@@ -88,7 +92,8 @@ private static int GetPrecedence(ReferencedSymbol referencedSymbol) ...@@ -88,7 +92,8 @@ private static int GetPrecedence(ReferencedSymbol referencedSymbol)
ArrayBuilder<DefinitionItem> definitions, ArrayBuilder<DefinitionItem> definitions,
ArrayBuilder<SourceReferenceItem> references, ArrayBuilder<SourceReferenceItem> references,
bool includeHiddenLocations, bool includeHiddenLocations,
HashSet<DocumentSpan> uniqueSpans) HashSet<DocumentSpan> uniqueSpans,
CancellationToken cancellationToken)
{ {
// See if this is a symbol we even want to present to the user. If not, // See if this is a symbol we even want to present to the user. If not,
// ignore it entirely (including all its reference locations). // ignore it entirely (including all its reference locations).
...@@ -109,7 +114,8 @@ private static int GetPrecedence(ReferencedSymbol referencedSymbol) ...@@ -109,7 +114,8 @@ private static int GetPrecedence(ReferencedSymbol referencedSymbol)
// Finally, see if there are any third parties that want to add their // Finally, see if there are any third parties that want to add their
// own result to our collection. // own result to our collection.
var thirdPartyItem = GetThirdPartyDefinitionItem(solution, referencedSymbol.Definition); var thirdPartyItem = GetThirdPartyDefinitionItem(
solution, referencedSymbol.Definition, cancellationToken);
if (thirdPartyItem != null) if (thirdPartyItem != null)
{ {
definitions.Add(thirdPartyItem); definitions.Add(thirdPartyItem);
...@@ -121,7 +127,7 @@ private static int GetPrecedence(ReferencedSymbol referencedSymbol) ...@@ -121,7 +127,7 @@ private static int GetPrecedence(ReferencedSymbol referencedSymbol)
/// results to the results found by the FindReferences engine. /// results to the results found by the FindReferences engine.
/// </summary> /// </summary>
public virtual DefinitionItem GetThirdPartyDefinitionItem( public virtual DefinitionItem GetThirdPartyDefinitionItem(
Solution solution, ISymbol definition) Solution solution, ISymbol definition, CancellationToken cancellationToken)
{ {
return null; return null;
} }
......
...@@ -12,12 +12,14 @@ public bool TryNavigateToSymbol(ISymbol symbol, Project project, OptionSet optio ...@@ -12,12 +12,14 @@ public bool TryNavigateToSymbol(ISymbol symbol, Project project, OptionSet optio
return false; return false;
} }
public bool TrySymbolNavigationNotify(ISymbol symbol, Solution solution) public bool TrySymbolNavigationNotify(ISymbol symbol, Solution solution, CancellationToken cancellationToken)
{ {
return false; return false;
} }
public bool WouldNavigateToSymbol(ISymbol symbol, Solution solution, out string filePath, out int lineNumber, out int charOffset) public bool WouldNavigateToSymbol(
ISymbol symbol, Solution solution, CancellationToken cancellationToken,
out string filePath, out int lineNumber, out int charOffset)
{ {
filePath = null; filePath = null;
lineNumber = 0; lineNumber = 0;
......
...@@ -21,9 +21,11 @@ internal interface ISymbolNavigationService : IWorkspaceService ...@@ -21,9 +21,11 @@ internal interface ISymbolNavigationService : IWorkspaceService
/// <returns>True if the navigation was handled, indicating that the caller should not /// <returns>True if the navigation was handled, indicating that the caller should not
/// perform the navigation.</returns> /// perform the navigation.</returns>
bool TrySymbolNavigationNotify(ISymbol symbol, Solution solution); bool TrySymbolNavigationNotify(ISymbol symbol, Solution solution, CancellationToken cancellationToken);
/// <returns>True if the navigation would be handled.</returns> /// <returns>True if the navigation would be handled.</returns>
bool WouldNavigateToSymbol(ISymbol symbol, Solution solution, out string filePath, out int lineNumber, out int charOffset); bool WouldNavigateToSymbol(
ISymbol symbol, Solution solution, CancellationToken cancellationToken,
out string filePath, out int lineNumber, out int charOffset);
} }
} }
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq; using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.GeneratedCodeRecognition; using Microsoft.CodeAnalysis.GeneratedCodeRecognition;
using Microsoft.CodeAnalysis.LanguageServices; using Microsoft.CodeAnalysis.LanguageServices;
...@@ -29,15 +30,16 @@ public static INavigableItem GetItemFromDeclaredSymbolInfo(DeclaredSymbolInfo de ...@@ -29,15 +30,16 @@ public static INavigableItem GetItemFromDeclaredSymbolInfo(DeclaredSymbolInfo de
public static IEnumerable<INavigableItem> GetItemsFromPreferredSourceLocations( public static IEnumerable<INavigableItem> GetItemsFromPreferredSourceLocations(
Solution solution, Solution solution,
ISymbol symbol, ISymbol symbol,
ImmutableArray<TaggedText>? displayTaggedParts) ImmutableArray<TaggedText>? displayTaggedParts,
CancellationToken cancellationToken)
{ {
var locations = GetPreferredSourceLocations(solution, symbol); var locations = GetPreferredSourceLocations(solution, symbol, cancellationToken);
return locations.Select(loc => GetItemFromSymbolLocation( return locations.Select(loc => GetItemFromSymbolLocation(
solution, symbol, loc, displayTaggedParts)); solution, symbol, loc, displayTaggedParts));
} }
public static IEnumerable<Location> GetPreferredSourceLocations( public static IEnumerable<Location> GetPreferredSourceLocations(
Solution solution, ISymbol symbol) Solution solution, ISymbol symbol, CancellationToken cancellationToken)
{ {
// Prefer non-generated source locations over generated ones. // Prefer non-generated source locations over generated ones.
...@@ -46,7 +48,7 @@ public static INavigableItem GetItemFromDeclaredSymbolInfo(DeclaredSymbolInfo de ...@@ -46,7 +48,7 @@ public static INavigableItem GetItemFromDeclaredSymbolInfo(DeclaredSymbolInfo de
var candidateLocationGroups = from c in sourceLocations var candidateLocationGroups = from c in sourceLocations
let doc = solution.GetDocument(c.SourceTree) let doc = solution.GetDocument(c.SourceTree)
where doc != null where doc != null
group c by doc.IsGeneratedCode(); group c by doc.IsGeneratedCode(cancellationToken);
var generatedSourceLocations = candidateLocationGroups.SingleOrDefault(g => g.Key) ?? SpecializedCollections.EmptyEnumerable<Location>(); var generatedSourceLocations = candidateLocationGroups.SingleOrDefault(g => g.Key) ?? SpecializedCollections.EmptyEnumerable<Location>();
var nonGeneratedSourceLocations = candidateLocationGroups.SingleOrDefault(g => !g.Key) ?? SpecializedCollections.EmptyEnumerable<Location>(); var nonGeneratedSourceLocations = candidateLocationGroups.SingleOrDefault(g => !g.Key) ?? SpecializedCollections.EmptyEnumerable<Location>();
...@@ -66,13 +68,16 @@ private static IEnumerable<Location> GetPreferredSourceLocations(ISymbol symbol) ...@@ -66,13 +68,16 @@ private static IEnumerable<Location> GetPreferredSourceLocations(ISymbol symbol)
: locations.Where(loc => loc.IsInSource); : locations.Where(loc => loc.IsInSource);
} }
public static IEnumerable<INavigableItem> GetPreferredNavigableItems(Solution solution, IEnumerable<INavigableItem> navigableItems) public static IEnumerable<INavigableItem> GetPreferredNavigableItems(
Solution solution,
IEnumerable<INavigableItem> navigableItems,
CancellationToken cancellationToken)
{ {
navigableItems = navigableItems.Where(n => n.Document != null); navigableItems = navigableItems.Where(n => n.Document != null);
var hasNonGeneratedCodeItem = navigableItems.Any(n => !n.Document.IsGeneratedCode()); var hasNonGeneratedCodeItem = navigableItems.Any(n => !n.Document.IsGeneratedCode(cancellationToken));
return hasNonGeneratedCodeItem return hasNonGeneratedCodeItem
? navigableItems.Where(n => !n.Document.IsGeneratedCode()) ? navigableItems.Where(n => !n.Document.IsGeneratedCode(cancellationToken))
: navigableItems.Where(n => n.Document.IsGeneratedCode()); : navigableItems.Where(n => n.Document.IsGeneratedCode(cancellationToken));
} }
public static ImmutableArray<TaggedText> GetSymbolDisplayTaggedParts(Project project, ISymbol symbol) public static ImmutableArray<TaggedText> GetSymbolDisplayTaggedParts(Project project, ISymbol symbol)
...@@ -121,4 +126,4 @@ private static SymbolDisplayFormat GetSymbolDisplayFormat(ISymbol symbol) ...@@ -121,4 +126,4 @@ private static SymbolDisplayFormat GetSymbolDisplayFormat(ISymbol symbol)
SymbolDisplayMemberOptions.IncludeExplicitInterface | SymbolDisplayMemberOptions.IncludeExplicitInterface |
SymbolDisplayMemberOptions.IncludeParameters); SymbolDisplayMemberOptions.IncludeParameters);
} }
} }
\ No newline at end of file
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Composition; using System.Composition;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Completion; using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.FindUsages; using Microsoft.CodeAnalysis.FindUsages;
...@@ -30,10 +31,12 @@ public VisualStudioDefinitionsAndReferencesFactory(SVsServiceProvider servicePro ...@@ -30,10 +31,12 @@ public VisualStudioDefinitionsAndReferencesFactory(SVsServiceProvider servicePro
} }
public override DefinitionItem GetThirdPartyDefinitionItem( public override DefinitionItem GetThirdPartyDefinitionItem(
Solution solution, ISymbol definition) Solution solution, ISymbol definition, CancellationToken cancellationToken)
{ {
var symbolNavigationService = solution.Workspace.Services.GetService<ISymbolNavigationService>(); var symbolNavigationService = solution.Workspace.Services.GetService<ISymbolNavigationService>();
if (!symbolNavigationService.WouldNavigateToSymbol(definition, solution, out var filePath, out var lineNumber, out var charOffset)) if (!symbolNavigationService.WouldNavigateToSymbol(
definition, solution, cancellationToken,
out var filePath, out var lineNumber, out var charOffset))
{ {
return null; return null;
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Security; using System.Security;
using System.Threading;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.GeneratedCodeRecognition; using Microsoft.CodeAnalysis.GeneratedCodeRecognition;
using Microsoft.CodeAnalysis.GenerateType; using Microsoft.CodeAnalysis.GenerateType;
...@@ -507,45 +508,43 @@ public int ProjectSelectIndex ...@@ -507,45 +508,43 @@ public int ProjectSelectIndex
private Project _previouslyPopulatedProject = null; private Project _previouslyPopulatedProject = null;
private List<DocumentSelectItem> _previouslyPopulatedDocumentList = null; private List<DocumentSelectItem> _previouslyPopulatedDocumentList = null;
public IEnumerable<DocumentSelectItem> DocumentList
public IEnumerable<DocumentSelectItem> GetDocumentList(CancellationToken cancellationToken)
{ {
get if (_previouslyPopulatedProject == _selectedProject)
{ {
if (_previouslyPopulatedProject == _selectedProject) return _previouslyPopulatedDocumentList;
{ }
return _previouslyPopulatedDocumentList;
}
_previouslyPopulatedProject = _selectedProject;
_previouslyPopulatedDocumentList = new List<DocumentSelectItem>();
// Check for the current project _previouslyPopulatedProject = _selectedProject;
if (_selectedProject == _document.Project) _previouslyPopulatedDocumentList = new List<DocumentSelectItem>();
{
// populate the current document
_previouslyPopulatedDocumentList.Add(new DocumentSelectItem(_document, "<Current File>"));
// Set the initial selected Document // Check for the current project
this.SelectedDocument = _document; if (_selectedProject == _document.Project)
{
// populate the current document
_previouslyPopulatedDocumentList.Add(new DocumentSelectItem(_document, "<Current File>"));
// Populate the rest of the documents for the project // Set the initial selected Document
_previouslyPopulatedDocumentList.AddRange(_document.Project.Documents this.SelectedDocument = _document;
.Where(d => d != _document && !d.IsGeneratedCode())
.Select(d => new DocumentSelectItem(d)));
}
else
{
_previouslyPopulatedDocumentList.AddRange(_selectedProject.Documents
.Where(d => !d.IsGeneratedCode())
.Select(d => new DocumentSelectItem(d)));
this.SelectedDocument = _selectedProject.Documents.FirstOrDefault(); // Populate the rest of the documents for the project
} _previouslyPopulatedDocumentList.AddRange(_document.Project.Documents
.Where(d => d != _document && !d.IsGeneratedCode(cancellationToken))
.Select(d => new DocumentSelectItem(d)));
}
else
{
_previouslyPopulatedDocumentList.AddRange(_selectedProject.Documents
.Where(d => !d.IsGeneratedCode(cancellationToken))
.Select(d => new DocumentSelectItem(d)));
this.IsExistingFileEnabled = _previouslyPopulatedDocumentList.Count == 0 ? false : true; this.SelectedDocument = _selectedProject.Documents.FirstOrDefault();
this.IsNewFile = this.IsExistingFileEnabled ? this.IsNewFile : true;
return _previouslyPopulatedDocumentList;
} }
this.IsExistingFileEnabled = _previouslyPopulatedDocumentList.Count == 0 ? false : true;
this.IsNewFile = this.IsExistingFileEnabled ? this.IsNewFile : true;
return _previouslyPopulatedDocumentList;
} }
private bool _isExistingFileEnabled = true; private bool _isExistingFileEnabled = true;
......
...@@ -81,7 +81,8 @@ public void NavigateTo(GraphObject graphObject) ...@@ -81,7 +81,8 @@ public void NavigateTo(GraphObject graphObject)
} }
} }
private void NavigateOnForegroundThread(SourceLocation sourceLocation, SymbolKey? symbolId, Project project, Document document) private void NavigateOnForegroundThread(
SourceLocation sourceLocation, SymbolKey? symbolId, Project project, Document document)
{ {
AssertIsForeground(); AssertIsForeground();
...@@ -95,7 +96,7 @@ private void NavigateOnForegroundThread(SourceLocation sourceLocation, SymbolKey ...@@ -95,7 +96,7 @@ private void NavigateOnForegroundThread(SourceLocation sourceLocation, SymbolKey
if (symbol != null && if (symbol != null &&
!(symbol is ITypeSymbol) && !(symbol is ITypeSymbol) &&
!symbol.IsConstructor() && !symbol.IsConstructor() &&
symbolNavigationService.TrySymbolNavigationNotify(symbol, project.Solution)) symbolNavigationService.TrySymbolNavigationNotify(symbol, project.Solution, CancellationToken.None))
{ {
return; return;
} }
......
...@@ -118,4 +118,4 @@ public PortableExecutableReference CreatePortableExecutableReference(string file ...@@ -118,4 +118,4 @@ public PortableExecutableReference CreatePortableExecutableReference(string file
return this.Services.GetService<IMetadataService>().GetReference(filePath, properties); return this.Services.GetService<IMetadataService>().GetReference(filePath, properties);
} }
} }
} }
\ No newline at end of file
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
using Microsoft.CodeAnalysis.Editor; using Microsoft.CodeAnalysis.Editor;
using Microsoft.CodeAnalysis.Editor.Implementation.Structure; using Microsoft.CodeAnalysis.Editor.Implementation.Structure;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.GeneratedCodeRecognition;
using Microsoft.CodeAnalysis.Navigation; using Microsoft.CodeAnalysis.Navigation;
using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Extensions;
...@@ -24,7 +23,6 @@ ...@@ -24,7 +23,6 @@
using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.TextManager.Interop; using Microsoft.VisualStudio.TextManager.Interop;
using Roslyn.Utilities; using Roslyn.Utilities;
using IOleServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
namespace Microsoft.VisualStudio.LanguageServices.Implementation namespace Microsoft.VisualStudio.LanguageServices.Implementation
{ {
...@@ -149,15 +147,18 @@ public bool TryNavigateToSymbol(ISymbol symbol, Project project, OptionSet optio ...@@ -149,15 +147,18 @@ public bool TryNavigateToSymbol(ISymbol symbol, Project project, OptionSet optio
return true; return true;
} }
public bool TrySymbolNavigationNotify(ISymbol symbol, Solution solution) public bool TrySymbolNavigationNotify(ISymbol symbol, Solution solution, CancellationToken cancellationToken)
{ {
return TryNotifyForSpecificSymbol(symbol, solution); return TryNotifyForSpecificSymbol(symbol, solution, cancellationToken);
} }
private bool TryNotifyForSpecificSymbol(ISymbol symbol, Solution solution) private bool TryNotifyForSpecificSymbol(
ISymbol symbol, Solution solution, CancellationToken cancellationToken)
{ {
AssertIsForeground(); AssertIsForeground();
if (!TryGetNavigationAPIRequiredArguments(symbol, solution, out var hierarchy, out var itemID, out var navigationNotify, out var rqname)) if (!TryGetNavigationAPIRequiredArguments(
symbol, solution, cancellationToken,
out var hierarchy, out var itemID, out var navigationNotify, out var rqname))
{ {
return false; return false;
} }
...@@ -176,16 +177,19 @@ private bool TryNotifyForSpecificSymbol(ISymbol symbol, Solution solution) ...@@ -176,16 +177,19 @@ private bool TryNotifyForSpecificSymbol(ISymbol symbol, Solution solution)
return false; return false;
} }
public bool WouldNavigateToSymbol(ISymbol symbol, Solution solution, out string filePath, out int lineNumber, out int charOffset) public bool WouldNavigateToSymbol(
ISymbol symbol, Solution solution, CancellationToken cancellationToken,
out string filePath, out int lineNumber, out int charOffset)
{ {
if (WouldNotifyToSpecificSymbol(symbol, solution, out filePath, out lineNumber, out charOffset)) if (WouldNotifyToSpecificSymbol(symbol, solution, cancellationToken, out filePath, out lineNumber, out charOffset))
{ {
return true; return true;
} }
// If the symbol being considered is a constructor and no third parties choose to // If the symbol being considered is a constructor and no third parties choose to
// navigate to the constructor, then try the constructor's containing type. // navigate to the constructor, then try the constructor's containing type.
if (symbol.IsConstructor() && WouldNotifyToSpecificSymbol(symbol.ContainingType, solution, out filePath, out lineNumber, out charOffset)) if (symbol.IsConstructor() && WouldNotifyToSpecificSymbol(
symbol.ContainingType, solution, cancellationToken, out filePath, out lineNumber, out charOffset))
{ {
return true; return true;
} }
...@@ -196,14 +200,18 @@ public bool WouldNavigateToSymbol(ISymbol symbol, Solution solution, out string ...@@ -196,14 +200,18 @@ public bool WouldNavigateToSymbol(ISymbol symbol, Solution solution, out string
return false; return false;
} }
public bool WouldNotifyToSpecificSymbol(ISymbol symbol, Solution solution, out string filePath, out int lineNumber, out int charOffset) public bool WouldNotifyToSpecificSymbol(
ISymbol symbol, Solution solution, CancellationToken cancellationToken,
out string filePath, out int lineNumber, out int charOffset)
{ {
AssertIsForeground(); AssertIsForeground();
filePath = null; filePath = null;
lineNumber = 0; lineNumber = 0;
charOffset = 0; charOffset = 0;
if (!TryGetNavigationAPIRequiredArguments(symbol, solution, out var hierarchy, out var itemID, out var navigationNotify, out var rqname)) if (!TryGetNavigationAPIRequiredArguments(
symbol, solution, cancellationToken,
out var hierarchy, out var itemID, out var navigationNotify, out var rqname))
{ {
return false; return false;
} }
...@@ -233,6 +241,7 @@ public bool WouldNotifyToSpecificSymbol(ISymbol symbol, Solution solution, out s ...@@ -233,6 +241,7 @@ public bool WouldNotifyToSpecificSymbol(ISymbol symbol, Solution solution, out s
private bool TryGetNavigationAPIRequiredArguments( private bool TryGetNavigationAPIRequiredArguments(
ISymbol symbol, ISymbol symbol,
Solution solution, Solution solution,
CancellationToken cancellationToken,
out IVsHierarchy hierarchy, out IVsHierarchy hierarchy,
out uint itemID, out uint itemID,
out IVsSymbolicNavigationNotify navigationNotify, out IVsSymbolicNavigationNotify navigationNotify,
...@@ -266,7 +275,7 @@ public bool WouldNotifyToSpecificSymbol(ISymbol symbol, Solution solution, out s ...@@ -266,7 +275,7 @@ public bool WouldNotifyToSpecificSymbol(ISymbol symbol, Solution solution, out s
// documents we consider to be "generated" to give external language services the best // documents we consider to be "generated" to give external language services the best
// chance of participating. // chance of participating.
var generatedDocuments = documents.Where(d => d.IsGeneratedCode()); var generatedDocuments = documents.Where(d => d.IsGeneratedCode(cancellationToken));
var documentToUse = generatedDocuments.FirstOrDefault() ?? documents.First(); var documentToUse = generatedDocuments.FirstOrDefault() ?? documents.First();
if (!TryGetVsHierarchyAndItemId(documentToUse, out hierarchy, out itemID)) if (!TryGetVsHierarchyAndItemId(documentToUse, out hierarchy, out itemID))
...@@ -310,4 +319,4 @@ private IVsRunningDocumentTable GetRunningDocumentTable() ...@@ -310,4 +319,4 @@ private IVsRunningDocumentTable GetRunningDocumentTable()
return runningDocumentTable; return runningDocumentTable;
} }
} }
} }
\ No newline at end of file
...@@ -600,7 +600,8 @@ protected EnvDTE.vsCMElement GetElementKind(ITypeSymbol typeSymbol) ...@@ -600,7 +600,8 @@ protected EnvDTE.vsCMElement GetElementKind(ITypeSymbol typeSymbol)
} }
} }
protected bool TryGetElementFromSource(CodeModelState state, Project project, ITypeSymbol typeSymbol, out EnvDTE.CodeElement element) protected bool TryGetElementFromSource(
CodeModelState state, Project project, ITypeSymbol typeSymbol, out EnvDTE.CodeElement element)
{ {
element = null; element = null;
...@@ -629,7 +630,7 @@ protected bool TryGetElementFromSource(CodeModelState state, Project project, IT ...@@ -629,7 +630,7 @@ protected bool TryGetElementFromSource(CodeModelState state, Project project, IT
{ {
var document = project.GetDocument(location.SourceTree); var document = project.GetDocument(location.SourceTree);
if (document.IsGeneratedCode() == false) if (!document.IsGeneratedCode(CancellationToken.None))
{ {
chosenLocation = location; chosenLocation = location;
chosenDocumentId = document.Id; chosenDocumentId = document.Id;
......
...@@ -142,7 +142,7 @@ internal override IInvisibleEditor OpenInvisibleEditor(IVisualStudioHostDocument ...@@ -142,7 +142,7 @@ internal override IInvisibleEditor OpenInvisibleEditor(IVisualStudioHostDocument
if (this.CurrentSolution.ContainsDocument(hostDocument.Id)) if (this.CurrentSolution.ContainsDocument(hostDocument.Id))
{ {
// Disable undo on generated documents // Disable undo on generated documents
needsUndoDisabled = this.CurrentSolution.GetDocument(hostDocument.Id).IsGeneratedCode(); needsUndoDisabled = this.CurrentSolution.GetDocument(hostDocument.Id).IsGeneratedCode(CancellationToken.None);
} }
else else
{ {
...@@ -232,7 +232,8 @@ public override bool TryFindAllReferences(ISymbol symbol, Project project, Cance ...@@ -232,7 +232,8 @@ public override bool TryFindAllReferences(ISymbol symbol, Project project, Cance
{ {
var service = this.Services.GetService<IDefinitionsAndReferencesFactory>(); var service = this.Services.GetService<IDefinitionsAndReferencesFactory>();
var definitionsAndReferences = service.CreateDefinitionsAndReferences( var definitionsAndReferences = service.CreateDefinitionsAndReferences(
solution, referencedSymbols, includeHiddenLocations: false); solution, referencedSymbols,
includeHiddenLocations: false, cancellationToken: CancellationToken.None);
foreach (var presenter in _referencedSymbolsPresenters) foreach (var presenter in _referencedSymbolsPresenters)
{ {
......
...@@ -151,7 +151,8 @@ using System.Threading; ...@@ -151,7 +151,8 @@ using System.Threading;
Dim factory = workspace.Services.GetService(Of IDefinitionsAndReferencesFactory) Dim factory = workspace.Services.GetService(Of IDefinitionsAndReferencesFactory)
Dim definitionsAndReferences = factory.CreateDefinitionsAndReferences( Dim definitionsAndReferences = factory.CreateDefinitionsAndReferences(
workspace.CurrentSolution, result, includeHiddenLocations:=False) workspace.CurrentSolution, result,
includeHiddenLocations:=False, cancellationToken:=CancellationToken.None)
Dim findReferencesTree = libraryManager.CreateFindReferencesItems(definitionsAndReferences) Dim findReferencesTree = libraryManager.CreateFindReferencesItems(definitionsAndReferences)
' We cannot control the ordering of top-level nodes in the Find Symbol References window, so do not consider ordering of these items here. ' We cannot control the ordering of top-level nodes in the Find Symbol References window, so do not consider ordering of these items here.
......
...@@ -196,18 +196,17 @@ namespace A ...@@ -196,18 +196,17 @@ namespace A
' Only 2 Projects can be selected because CS2 and CS3 will introduce cyclic dependency ' Only 2 Projects can be selected because CS2 and CS3 will introduce cyclic dependency
Assert.Equal(2, viewModel.ProjectList.Count) Assert.Equal(2, viewModel.ProjectList.Count)
Assert.Equal(2, viewModel.DocumentList.Count) Assert.Equal(2, viewModel.GetDocumentList(CancellationToken.None).Count)
viewModel.DocumentSelectIndex = 1 viewModel.DocumentSelectIndex = 1
Dim projectToSelect = viewModel.ProjectList.Where(Function(p) p.Name = "VB1").Single().Project Dim projectToSelect = viewModel.ProjectList.Where(Function(p) p.Name = "VB1").Single().Project
Dim monitor = New PropertyChangedTestMonitor(viewModel) Dim monitor = New PropertyChangedTestMonitor(viewModel)
monitor.AddExpectation(Function() viewModel.DocumentList)
' Check to see if the values are reset when there is a change in the project selection ' Check to see if the values are reset when there is a change in the project selection
viewModel.SelectedProject = projectToSelect viewModel.SelectedProject = projectToSelect
Assert.Equal(2, viewModel.DocumentList.Count()) Assert.Equal(2, viewModel.GetDocumentList(CancellationToken.None).Count())
Assert.Equal(0, viewModel.DocumentSelectIndex) Assert.Equal(0, viewModel.DocumentSelectIndex)
Assert.Equal(1, viewModel.ProjectSelectIndex) Assert.Equal(1, viewModel.ProjectSelectIndex)
...@@ -249,7 +248,7 @@ namespace A ...@@ -249,7 +248,7 @@ namespace A
' Check if the option for Existing File is disabled ' Check if the option for Existing File is disabled
Assert.Equal(0, viewModel.DocumentList.Count()) Assert.Equal(0, viewModel.GetDocumentList(CancellationToken.None).Count())
Assert.Equal(False, viewModel.IsExistingFileEnabled) Assert.Equal(False, viewModel.IsExistingFileEnabled)
' Select the project CS1 which has documents ' Select the project CS1 which has documents
...@@ -257,7 +256,7 @@ namespace A ...@@ -257,7 +256,7 @@ namespace A
viewModel.SelectedProject = projectToSelect viewModel.SelectedProject = projectToSelect
' Check if the option for Existing File is enabled ' Check if the option for Existing File is enabled
Assert.Equal(2, viewModel.DocumentList.Count()) Assert.Equal(2, viewModel.GetDocumentList(CancellationToken.None).Count())
Assert.Equal(True, viewModel.IsExistingFileEnabled) Assert.Equal(True, viewModel.IsExistingFileEnabled)
End Function End Function
...@@ -587,7 +586,7 @@ class Program ...@@ -587,7 +586,7 @@ class Program
Dim viewModel = Await GetViewModelAsync(workspaceXml, LanguageNames.CSharp) Dim viewModel = Await GetViewModelAsync(workspaceXml, LanguageNames.CSharp)
Dim expectedDocuments = {"Test1.cs", "Test2.cs", "AssemblyInfo.cs", "Test3.cs"} Dim expectedDocuments = {"Test1.cs", "Test2.cs", "AssemblyInfo.cs", "Test3.cs"}
Assert.Equal(expectedDocuments, viewModel.DocumentList.Select(Function(d) d.Document.Name).ToArray()) Assert.Equal(expectedDocuments, viewModel.GetDocumentList(CancellationToken.None).Select(Function(d) d.Document.Name).ToArray())
End Function End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateType)> <Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateType)>
......
...@@ -1602,10 +1602,14 @@ public SeparatedSyntaxList<SyntaxNode> GetArgumentsOfInvocationExpression(Syntax ...@@ -1602,10 +1602,14 @@ public SeparatedSyntaxList<SyntaxNode> GetArgumentsOfInvocationExpression(Syntax
return ((invocationExpression as InvocationExpressionSyntax)?.ArgumentList.Arguments).Value; return ((invocationExpression as InvocationExpressionSyntax)?.ArgumentList.Arguments).Value;
} }
public bool IsRegularComment(SyntaxTrivia trivia)
=> trivia.IsRegularComment();
public bool IsDocumentationComment(SyntaxTrivia trivia)
=> trivia.IsDocComment();
public bool IsDocumentationComment(SyntaxNode node) public bool IsDocumentationComment(SyntaxNode node)
{ => SyntaxFacts.IsDocumentationCommentTrivia(node.Kind());
return SyntaxFacts.IsDocumentationCommentTrivia(node.Kind());
}
public bool IsUsingOrExternOrImport(SyntaxNode node) public bool IsUsingOrExternOrImport(SyntaxNode node)
{ {
......
...@@ -54,7 +54,9 @@ public abstract class DiagnosticProvider ...@@ -54,7 +54,9 @@ public abstract class DiagnosticProvider
internal virtual async Task<ImmutableDictionary<Document, ImmutableArray<Diagnostic>>> GetDocumentDiagnosticsToFixWorkerAsync( internal virtual async Task<ImmutableDictionary<Document, ImmutableArray<Diagnostic>>> GetDocumentDiagnosticsToFixWorkerAsync(
FixAllContext fixAllContext) FixAllContext fixAllContext)
{ {
using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Diagnostics, fixAllContext.CancellationToken)) var cancellationToken = fixAllContext.CancellationToken;
using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Diagnostics, cancellationToken))
{ {
var allDiagnostics = ImmutableArray<Diagnostic>.Empty; var allDiagnostics = ImmutableArray<Diagnostic>.Empty;
var projectsToFix = ImmutableArray<Project>.Empty; var projectsToFix = ImmutableArray<Project>.Empty;
...@@ -65,7 +67,7 @@ public abstract class DiagnosticProvider ...@@ -65,7 +67,7 @@ public abstract class DiagnosticProvider
switch (fixAllContext.Scope) switch (fixAllContext.Scope)
{ {
case FixAllScope.Document: case FixAllScope.Document:
if (document != null && !document.IsGeneratedCode()) if (document != null && !document.IsGeneratedCode(cancellationToken))
{ {
var documentDiagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false); var documentDiagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
var kvp = SpecializedCollections.SingletonEnumerable(KeyValuePair.Create(document, documentDiagnostics)); var kvp = SpecializedCollections.SingletonEnumerable(KeyValuePair.Create(document, documentDiagnostics));
...@@ -91,19 +93,19 @@ public abstract class DiagnosticProvider ...@@ -91,19 +93,19 @@ public abstract class DiagnosticProvider
var tasks = new Task[projectsToFix.Length]; var tasks = new Task[projectsToFix.Length];
for (int i = 0; i < projectsToFix.Length; i++) for (int i = 0; i < projectsToFix.Length; i++)
{ {
fixAllContext.CancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
var projectToFix = projectsToFix[i]; var projectToFix = projectsToFix[i];
tasks[i] = Task.Run(async () => tasks[i] = Task.Run(async () =>
{ {
var projectDiagnostics = await fixAllContext.GetAllDiagnosticsAsync(projectToFix).ConfigureAwait(false); var projectDiagnostics = await fixAllContext.GetAllDiagnosticsAsync(projectToFix).ConfigureAwait(false);
foreach (var diagnostic in projectDiagnostics) foreach (var diagnostic in projectDiagnostics)
{ {
fixAllContext.CancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
diagnostics.Add(diagnostic); diagnostics.Add(diagnostic);
} }
progressTracker.ItemCompleted(); progressTracker.ItemCompleted();
}, fixAllContext.CancellationToken); }, cancellationToken);
} }
await Task.WhenAll(tasks).ConfigureAwait(false); await Task.WhenAll(tasks).ConfigureAwait(false);
...@@ -116,7 +118,8 @@ public abstract class DiagnosticProvider ...@@ -116,7 +118,8 @@ public abstract class DiagnosticProvider
return ImmutableDictionary<Document, ImmutableArray<Diagnostic>>.Empty; return ImmutableDictionary<Document, ImmutableArray<Diagnostic>>.Empty;
} }
return await GetDocumentDiagnosticsToFixAsync(allDiagnostics, projectsToFix, fixAllContext.CancellationToken).ConfigureAwait(false); return await GetDocumentDiagnosticsToFixAsync(
allDiagnostics, projectsToFix, fixAllContext.CancellationToken).ConfigureAwait(false);
} }
} }
...@@ -132,7 +135,7 @@ public abstract class DiagnosticProvider ...@@ -132,7 +135,7 @@ public abstract class DiagnosticProvider
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
var document = documentAndDiagnostics.Key; var document = documentAndDiagnostics.Key;
if (!document.IsGeneratedCode()) if (!document.IsGeneratedCode(cancellationToken))
{ {
var diagnosticsForDocument = documentAndDiagnostics.ToImmutableArray(); var diagnosticsForDocument = documentAndDiagnostics.ToImmutableArray();
builder.Add(document, diagnosticsForDocument); builder.Add(document, diagnosticsForDocument);
......
...@@ -53,9 +53,7 @@ protected static TextSpan GetSpan(SyntaxNode node) ...@@ -53,9 +53,7 @@ protected static TextSpan GetSpan(SyntaxNode node)
} }
public bool CanAddTo(SyntaxNode destination, Solution solution, CancellationToken cancellationToken) public bool CanAddTo(SyntaxNode destination, Solution solution, CancellationToken cancellationToken)
{ => CanAddTo(destination, solution, cancellationToken, out var availableIndices);
return CanAddTo(destination, solution, cancellationToken, out var availableIndices);
}
private bool CanAddTo(SyntaxNode destination, Solution solution, CancellationToken cancellationToken, private bool CanAddTo(SyntaxNode destination, Solution solution, CancellationToken cancellationToken,
out IList<bool> availableIndices, bool checkGeneratedCode = false) out IList<bool> availableIndices, bool checkGeneratedCode = false)
...@@ -75,7 +73,7 @@ public bool CanAddTo(SyntaxNode destination, Solution solution, CancellationToke ...@@ -75,7 +73,7 @@ public bool CanAddTo(SyntaxNode destination, Solution solution, CancellationToke
} }
// check for generated files if needed. // check for generated files if needed.
if (checkGeneratedCode && document.IsGeneratedCode()) if (checkGeneratedCode && document.IsGeneratedCode(cancellationToken))
{ {
return false; return false;
} }
...@@ -202,4 +200,4 @@ private static async Task<SyntaxNode> SelectFirstOrDefaultAsync(IEnumerable<Synt ...@@ -202,4 +200,4 @@ private static async Task<SyntaxNode> SelectFirstOrDefaultAsync(IEnumerable<Synt
return null; return null;
} }
} }
} }
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // 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.Composition; using System.Composition;
using System.IO; using System.Threading;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.GeneratedCodeRecognition namespace Microsoft.CodeAnalysis.GeneratedCodeRecognition
{ {
[ExportWorkspaceServiceFactory(typeof(IGeneratedCodeRecognitionService), ServiceLayer.Default), Shared] [ExportWorkspaceService(typeof(IGeneratedCodeRecognitionService)), Shared]
internal class GeneratedCodeRecognitionServiceFactory : IWorkspaceServiceFactory internal class GeneratedCodeRecognitionService : IGeneratedCodeRecognitionService
{ {
private static readonly IGeneratedCodeRecognitionService s_singleton = new GeneratedCodeRecognitionService();
public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) public bool IsGeneratedCode(Document document, CancellationToken cancellationToken)
{ {
return s_singleton; var syntaxTree = document.GetSyntaxTreeSynchronously(cancellationToken);
} var syntaxFacts = document.GetLanguageService<ISyntaxFactsService>();
return GeneratedCodeUtilities.IsGeneratedCode(
private class GeneratedCodeRecognitionService : IGeneratedCodeRecognitionService syntaxTree, t => syntaxFacts.IsRegularComment(t) || syntaxFacts.IsDocumentationComment(t), cancellationToken);
{
public bool IsGeneratedCode(Document document)
{
return IsFileNameForGeneratedCode(document.Name);
}
private static bool IsFileNameForGeneratedCode(string fileName)
{
if (fileName.StartsWith("TemporaryGeneratedFile_", StringComparison.OrdinalIgnoreCase))
{
return true;
}
string extension = Path.GetExtension(fileName);
if (extension != string.Empty)
{
fileName = Path.GetFileNameWithoutExtension(fileName);
if (fileName.EndsWith(".designer", StringComparison.OrdinalIgnoreCase) ||
fileName.EndsWith(".generated", StringComparison.OrdinalIgnoreCase) ||
fileName.EndsWith(".g", StringComparison.OrdinalIgnoreCase) ||
fileName.EndsWith(".g.i", StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
} }
} }
} }
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // 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.Threading;
using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Host;
namespace Microsoft.CodeAnalysis.GeneratedCodeRecognition namespace Microsoft.CodeAnalysis.GeneratedCodeRecognition
{ {
internal interface IGeneratedCodeRecognitionService : IWorkspaceService internal interface IGeneratedCodeRecognitionService : IWorkspaceService
{ {
bool IsGeneratedCode(Document document); bool IsGeneratedCode(Document document, CancellationToken cancellationToken);
} }
} }
\ No newline at end of file
...@@ -36,11 +36,15 @@ internal interface ISyntaxFactsService : ILanguageService ...@@ -36,11 +36,15 @@ internal interface ISyntaxFactsService : ILanguageService
bool IsTypeNamedVarInVariableOrFieldDeclaration(SyntaxToken token, SyntaxNode parent); bool IsTypeNamedVarInVariableOrFieldDeclaration(SyntaxToken token, SyntaxNode parent);
bool IsTypeNamedDynamic(SyntaxToken token, SyntaxNode parent); bool IsTypeNamedDynamic(SyntaxToken token, SyntaxNode parent);
bool IsDocumentationComment(SyntaxNode node);
bool IsUsingOrExternOrImport(SyntaxNode node); bool IsUsingOrExternOrImport(SyntaxNode node);
bool IsGlobalAttribute(SyntaxNode node); bool IsGlobalAttribute(SyntaxNode node);
bool IsDeclaration(SyntaxNode node); bool IsDeclaration(SyntaxNode node);
bool IsRegularComment(SyntaxTrivia trivia);
bool IsDocumentationComment(SyntaxTrivia trivia);
bool IsDocumentationComment(SyntaxNode node);
bool IsNumericLiteralExpression(SyntaxNode node); bool IsNumericLiteralExpression(SyntaxNode node);
bool IsNullLiteralExpression(SyntaxNode node); bool IsNullLiteralExpression(SyntaxNode node);
......
...@@ -190,11 +190,11 @@ public static async Task<SemanticModel> GetPartialSemanticModelAsync(this Docume ...@@ -190,11 +190,11 @@ public static async Task<SemanticModel> GetPartialSemanticModelAsync(this Docume
} }
} }
public static bool IsGeneratedCode(this Document document) public static bool IsGeneratedCode(this Document document, CancellationToken cancellationToken)
{ {
var solution = document.Project.Solution; var solution = document.Project.Solution;
var generatedCodeRecognitionService = solution.Workspace.Services.GetService<IGeneratedCodeRecognitionService>(); var generatedCodeRecognitionService = solution.Workspace.Services.GetService<IGeneratedCodeRecognitionService>();
return generatedCodeRecognitionService != null && generatedCodeRecognitionService.IsGeneratedCode(document); return generatedCodeRecognitionService?.IsGeneratedCode(document, cancellationToken) == true;
} }
} }
} }
\ No newline at end of file
...@@ -19,5 +19,8 @@ public static bool IsWord(this ISyntaxFactsService syntaxFacts, SyntaxToken toke ...@@ -19,5 +19,8 @@ public static bool IsWord(this ISyntaxFactsService syntaxFacts, SyntaxToken toke
{ {
return syntaxFacts.IsSimpleMemberAccessExpression(node) || syntaxFacts.IsPointerMemberAccessExpression(node); return syntaxFacts.IsSimpleMemberAccessExpression(node) || syntaxFacts.IsPointerMemberAccessExpression(node);
} }
public static bool IsRegularOrDocumentationComment(this ISyntaxFactsService syntaxFacts, SyntaxTrivia trivia)
=> syntaxFacts.IsRegularComment(trivia) || syntaxFacts.IsDocumentationComment(trivia);
} }
} }
\ No newline at end of file
...@@ -90,6 +90,9 @@ ...@@ -90,6 +90,9 @@
<Compile Include="..\..\..\Compilers\Core\Portable\InternalUtilities\FileNameUtilities.cs"> <Compile Include="..\..\..\Compilers\Core\Portable\InternalUtilities\FileNameUtilities.cs">
<Link>InternalUtilities\PathUtilities.cs</Link> <Link>InternalUtilities\PathUtilities.cs</Link>
</Compile> </Compile>
<Compile Include="..\..\..\Compilers\Core\Portable\InternalUtilities\GeneratedCodeUtilities.cs">
<Link>InternalUtilities\GeneratedCodeUtilities.cs</Link>
</Compile>
<Compile Include="..\..\..\Compilers\Core\Portable\InternalUtilities\Hash.cs"> <Compile Include="..\..\..\Compilers\Core\Portable\InternalUtilities\Hash.cs">
<Link>InternalUtilities\Hash.cs</Link> <Link>InternalUtilities\Hash.cs</Link>
</Compile> </Compile>
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // 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.Threading;
using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Extensions;
using Xunit; using Xunit;
...@@ -53,11 +54,11 @@ private static void TestFileNames(bool assertGenerated, params string[] fileName ...@@ -53,11 +54,11 @@ private static void TestFileNames(bool assertGenerated, params string[] fileName
var document = project.AddDocument(fileName, ""); var document = project.AddDocument(fileName, "");
if (assertGenerated) if (assertGenerated)
{ {
Assert.True(document.IsGeneratedCode(), string.Format("Expected file '{0}' to be interpreted as generated code", fileName)); Assert.True(document.IsGeneratedCode(CancellationToken.None), string.Format("Expected file '{0}' to be interpreted as generated code", fileName));
} }
else else
{ {
Assert.False(document.IsGeneratedCode(), string.Format("Did not expect file '{0}' to be interpreted as generated code", fileName)); Assert.False(document.IsGeneratedCode(CancellationToken.None), string.Format("Did not expect file '{0}' to be interpreted as generated code", fileName));
} }
} }
} }
......
...@@ -1632,5 +1632,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -1632,5 +1632,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Public Function IsEndOfLineTrivia(trivia As SyntaxTrivia) As Boolean Implements ISyntaxFactsService.IsEndOfLineTrivia Public Function IsEndOfLineTrivia(trivia As SyntaxTrivia) As Boolean Implements ISyntaxFactsService.IsEndOfLineTrivia
Return trivia.IsEndOfLine() Return trivia.IsEndOfLine()
End Function End Function
Public Function IsRegularComment(trivia As SyntaxTrivia) As Boolean Implements ISyntaxFactsService.IsRegularComment
Return trivia.Kind = SyntaxKind.CommentTrivia
End Function
Public Function IsDocumentationComment(trivia As SyntaxTrivia) As Boolean Implements ISyntaxFactsService.IsDocumentationComment
Return trivia.Kind = SyntaxKind.DocumentationCommentTrivia
End Function
End Class End Class
End Namespace End Namespace
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册