提交 a1e70603 编写于 作者: T Tomas Matousek

Add more filters

上级 cf24e4d5
// 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.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
...@@ -8,6 +9,7 @@ ...@@ -8,6 +9,7 @@
using Microsoft.CodeAnalysis.Completion.Providers; using Microsoft.CodeAnalysis.Completion.Providers;
using Microsoft.CodeAnalysis.CSharp.Extensions; using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Extensions.ContextQuery; using Microsoft.CodeAnalysis.CSharp.Extensions.ContextQuery;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.LanguageServices; using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Extensions;
...@@ -38,73 +40,80 @@ public override bool IsTriggerCharacter(SourceText text, int characterPosition, ...@@ -38,73 +40,80 @@ public override bool IsTriggerCharacter(SourceText text, int characterPosition,
Document document, int position, CompletionTriggerInfo triggerInfo, Document document, int position, CompletionTriggerInfo triggerInfo,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); try
if (tree.IsInNonUserCode(position, cancellationToken))
{ {
return null; var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
} if (tree.IsInNonUserCode(position, cancellationToken))
{
return null;
}
var token = tree.FindTokenOnLeftOfPosition(position, cancellationToken); var token = tree.FindTokenOnLeftOfPosition(position, cancellationToken);
if (token.IsMandatoryNamedParameterPosition()) if (token.IsMandatoryNamedParameterPosition())
{ {
return null; return null;
} }
var typeInferenceService = document.GetLanguageService<ITypeInferenceService>(); var typeInferenceService = document.GetLanguageService<ITypeInferenceService>();
var span = new TextSpan(position, 0); var span = new TextSpan(position, 0);
var semanticModel = await document.GetSemanticModelForSpanAsync(span, cancellationToken).ConfigureAwait(false); var semanticModel = await document.GetSemanticModelForSpanAsync(span, cancellationToken).ConfigureAwait(false);
var type = typeInferenceService.InferType(semanticModel, position, var type = typeInferenceService.InferType(semanticModel, position,
objectAsDefault: true, objectAsDefault: true,
cancellationToken: cancellationToken); cancellationToken: cancellationToken);
// If we have a Nullable<T>, unwrap it. // If we have a Nullable<T>, unwrap it.
if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T)
{ {
type = type.GetTypeArguments().FirstOrDefault(); type = type.GetTypeArguments().FirstOrDefault();
if (type == null) if (type == null)
{
return null;
}
}
if (type.TypeKind != TypeKind.Enum)
{ {
return null; type = GetCompletionListType(type, semanticModel.GetEnclosingNamedType(position, cancellationToken), semanticModel.Compilation);
if (type == null)
{
return null;
}
} }
}
if (type.TypeKind != TypeKind.Enum) if (!type.IsEditorBrowsable(document.ShouldHideAdvancedMembers(), semanticModel.Compilation))
{
type = GetCompletionListType(type, semanticModel.GetEnclosingNamedType(position, cancellationToken), semanticModel.Compilation);
if (type == null)
{ {
return null; return null;
} }
}
if (!type.IsEditorBrowsable(document.ShouldHideAdvancedMembers(), semanticModel.Compilation)) // Does type have any aliases?
{ ISymbol alias = await type.FindApplicableAlias(position, semanticModel, cancellationToken).ConfigureAwait(false);
return null;
}
// Does type have any aliases?
ISymbol alias = await type.FindApplicableAlias(position, semanticModel, cancellationToken).ConfigureAwait(false);
var displayService = document.GetLanguageService<ISymbolDisplayService>(); var displayService = document.GetLanguageService<ISymbolDisplayService>();
var displayText = alias != null var displayText = alias != null
? alias.Name ? alias.Name
: displayService.ToMinimalDisplayString(semanticModel, position, type); : displayService.ToMinimalDisplayString(semanticModel, position, type);
var workspace = document.Project.Solution.Workspace; var workspace = document.Project.Solution.Workspace;
var text = await semanticModel.SyntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false); var text = await semanticModel.SyntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false);
var textChangeSpan = CompletionUtilities.GetTextChangeSpan(text, position); var textChangeSpan = CompletionUtilities.GetTextChangeSpan(text, position);
var item = new CompletionItem( var item = new CompletionItem(
this, this,
displayText: displayText, displayText: displayText,
filterSpan: textChangeSpan, filterSpan: textChangeSpan,
descriptionFactory: CommonCompletionUtilities.CreateDescriptionFactory(workspace, semanticModel, position, alias ?? type), descriptionFactory: CommonCompletionUtilities.CreateDescriptionFactory(workspace, semanticModel, position, alias ?? type),
glyph: (alias ?? type).GetGlyph(), glyph: (alias ?? type).GetGlyph(),
preselect: true, preselect: true,
rules: ItemRules.Instance); rules: ItemRules.Instance);
return SpecializedCollections.SingletonEnumerable(item); return SpecializedCollections.SingletonEnumerable(item);
}
catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
{
throw ExceptionUtilities.Unreachable;
}
} }
private INamedTypeSymbol GetCompletionListType(ITypeSymbol type, INamedTypeSymbol within, Compilation compilation) private INamedTypeSymbol GetCompletionListType(ITypeSymbol type, INamedTypeSymbol within, Compilation compilation)
......
// 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.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
...@@ -8,6 +9,7 @@ ...@@ -8,6 +9,7 @@
using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Simplification; using Microsoft.CodeAnalysis.Simplification;
using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.Text;
...@@ -49,25 +51,31 @@ public static bool ContainingTypesOrSelfHasUnsafeKeyword(this ITypeSymbol contai ...@@ -49,25 +51,31 @@ public static bool ContainingTypesOrSelfHasUnsafeKeyword(this ITypeSymbol contai
public static async Task<ISymbol> FindApplicableAlias(this ITypeSymbol type, int position, SemanticModel semanticModel, CancellationToken cancellationToken) public static async Task<ISymbol> FindApplicableAlias(this ITypeSymbol type, int position, SemanticModel semanticModel, CancellationToken cancellationToken)
{ {
if (semanticModel.IsSpeculativeSemanticModel) try {
{ if (semanticModel.IsSpeculativeSemanticModel)
position = semanticModel.OriginalPositionForSpeculation; {
semanticModel = semanticModel.ParentModel; position = semanticModel.OriginalPositionForSpeculation;
} semanticModel = semanticModel.ParentModel;
}
var root = await semanticModel.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); var root = await semanticModel.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
IEnumerable<UsingDirectiveSyntax> applicableUsings = GetApplicableUsings(position, root as CompilationUnitSyntax); IEnumerable<UsingDirectiveSyntax> applicableUsings = GetApplicableUsings(position, root as CompilationUnitSyntax);
foreach (var applicableUsing in applicableUsings) foreach (var applicableUsing in applicableUsings)
{
var alias = semanticModel.GetOriginalSemanticModel().GetDeclaredSymbol(applicableUsing, cancellationToken);
if (alias != null && alias.Target == type)
{ {
return alias; var alias = semanticModel.GetOriginalSemanticModel().GetDeclaredSymbol(applicableUsing, cancellationToken);
if (alias != null && alias.Target == type)
{
return alias;
}
} }
}
return null; return null;
}
catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
{
throw ExceptionUtilities.Unreachable;
}
} }
private static IEnumerable<UsingDirectiveSyntax> GetApplicableUsings(int position, SyntaxNode root) private static IEnumerable<UsingDirectiveSyntax> GetApplicableUsings(int position, SyntaxNode root)
......
// 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.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.LanguageServices; using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.SemanticModelWorkspaceService; using Microsoft.CodeAnalysis.SemanticModelWorkspaceService;
using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Shared.Extensions namespace Microsoft.CodeAnalysis.Shared.Extensions
{ {
...@@ -39,22 +42,29 @@ public static bool IsOpen(this Document document) ...@@ -39,22 +42,29 @@ public static bool IsOpen(this Document document)
/// </summary> /// </summary>
public static async Task<SemanticModel> GetSemanticModelForSpanAsync(this Document document, TextSpan span, CancellationToken cancellationToken) public static async Task<SemanticModel> GetSemanticModelForSpanAsync(this Document document, TextSpan span, CancellationToken cancellationToken)
{ {
var syntaxFactService = document.Project.LanguageServices.GetService<ISyntaxFactsService>(); try
var semanticModelService = document.Project.Solution.Workspace.Services.GetService<ISemanticModelService>();
if (semanticModelService == null || syntaxFactService == null)
{ {
return await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var syntaxFactService = document.Project.LanguageServices.GetService<ISyntaxFactsService>();
var semanticModelService = document.Project.Solution.Workspace.Services.GetService<ISemanticModelService>();
if (semanticModelService == null || syntaxFactService == null)
{
return await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
}
var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
var token = root.FindToken(span.Start);
if (token.Parent == null)
{
return await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
}
var node = token.Parent.AncestorsAndSelf().FirstOrDefault(a => a.FullSpan.Contains(span));
return await GetSemanticModelForNodeAsync(semanticModelService, syntaxFactService, document, node, span, cancellationToken).ConfigureAwait(false);
} }
catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
var token = root.FindToken(span.Start);
if (token.Parent == null)
{ {
return await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); throw ExceptionUtilities.Unreachable;
} }
var node = token.Parent.AncestorsAndSelf().FirstOrDefault(a => a.FullSpan.Contains(span));
return await GetSemanticModelForNodeAsync(semanticModelService, syntaxFactService, document, node, span, cancellationToken).ConfigureAwait(false);
} }
/// <summary> /// <summary>
...@@ -124,21 +134,28 @@ public static bool IsFromPrimaryBranch(this Document document) ...@@ -124,21 +134,28 @@ public static bool IsFromPrimaryBranch(this Document document)
public static async Task<bool> IsForkedDocumentWithSyntaxChangesAsync(this Document document, CancellationToken cancellationToken) public static async Task<bool> IsForkedDocumentWithSyntaxChangesAsync(this Document document, CancellationToken cancellationToken)
{ {
if (document.IsFromPrimaryBranch()) try
{ {
return false; if (document.IsFromPrimaryBranch())
{
return false;
}
var currentSolution = document.Project.Solution.Workspace.CurrentSolution;
var currentDocument = currentSolution.GetDocument(document.Id);
if (currentDocument == null)
{
return true;
}
var documentVersion = await document.GetSyntaxVersionAsync(cancellationToken).ConfigureAwait(false);
var currentDocumentVersion = await currentDocument.GetSyntaxVersionAsync(cancellationToken).ConfigureAwait(false);
return !documentVersion.Equals(currentDocumentVersion);
} }
catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
var currentSolution = document.Project.Solution.Workspace.CurrentSolution;
var currentDocument = currentSolution.GetDocument(document.Id);
if (currentDocument == null)
{ {
return true; throw ExceptionUtilities.Unreachable;
} }
var documentVersion = await document.GetSyntaxVersionAsync(cancellationToken).ConfigureAwait(false);
var currentDocumentVersion = await currentDocument.GetSyntaxVersionAsync(cancellationToken).ConfigureAwait(false);
return !documentVersion.Equals(currentDocumentVersion);
} }
public static async Task<IEnumerable<DeclaredSymbolInfo>> GetDeclaredSymbolInfosAsync(this Document document, CancellationToken cancellationToken) public static async Task<IEnumerable<DeclaredSymbolInfo>> GetDeclaredSymbolInfosAsync(this Document document, CancellationToken cancellationToken)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册