private async Task <NameDeclarationInfo> GetResultsAsync(string markup) { var(document, position) = ApplyChangesToFixture(markup); var result = await NameDeclarationInfo.GetDeclarationInfo(document, position, CancellationToken.None); return(result); }
public override async Task ProvideCompletionsAsync(CompletionContext completionContext) { try { var position = completionContext.Position; var document = completionContext.Document; var cancellationToken = completionContext.CancellationToken; if (!completionContext.CompletionOptions.ShowNameSuggestions) { return; } var context = (CSharpSyntaxContext)await completionContext.GetSyntaxContextWithExistingSpeculativeModelAsync(document, cancellationToken).ConfigureAwait(false); if (context.IsInNonUserCode) { return; } // Do not show name suggestions for unbound "async" identifier. // Most likely user is writing an async method, so name suggestion will just interfere him if (context.TargetToken.IsKindOrHasMatchingText(SyntaxKind.AsyncKeyword) && context.SemanticModel.GetSymbolInfo(context.TargetToken).GetAnySymbol() is null) { return; } var nameInfo = await NameDeclarationInfo.GetDeclarationInfoAsync(document, position, cancellationToken).ConfigureAwait(false); using var _ = ArrayBuilder <(string name, SymbolKind kind)> .GetInstance(out var result); // Suggest names from existing overloads. if (nameInfo.PossibleSymbolKinds.Any(static k => k.SymbolKind == SymbolKind.Parameter))
private async Task <IEnumerable <(string, SymbolKind)> > GetRecommendedNamesAsync( IEnumerable <IEnumerable <string> > baseNames, NameDeclarationInfo declarationInfo, CSharpSyntaxContext context, Document document, CancellationToken cancellationToken) { var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); var namingStyleOptions = options.GetOption(SimplificationOptions.NamingPreferences); var rules = namingStyleOptions.CreateRules().NamingRules.Concat(s_BuiltInRules); var result = new Dictionary <string, SymbolKind>(); foreach (var symbolKind in declarationInfo.PossibleSymbolKinds) { var kind = new SymbolKindOrTypeKind(symbolKind); var modifiers = declarationInfo.Modifiers; foreach (var rule in rules) { if (rule.SymbolSpecification.AppliesTo(kind, declarationInfo.Modifiers, declarationInfo.DeclaredAccessibility)) { foreach (var baseName in baseNames) { var name = rule.NamingStyle.CreateName(baseName); if (name.Length > 1 && !result.ContainsKey(name)) // Don't add multiple items for the same name { result.Add(name, symbolKind); } } } } } return(result.Select(kvp => (kvp.Key, kvp.Value))); }
private static bool IsPossibleVariableOrLocalMethodDeclaration( SyntaxToken token, SemanticModel semanticModel, int position, CancellationToken cancellationToken, out NameDeclarationInfo result) { result = IsLastTokenOfType <ExpressionStatementSyntax>( token, semanticModel, e => e.Expression, _ => default(SyntaxTokenList), _ => ImmutableArray.Create(SymbolKind.Local), cancellationToken); return(result.Type != null); }
private ImmutableArray <ImmutableArray <string> > GetBaseNames( SemanticModel semanticModel, NameDeclarationInfo nameInfo ) { if (nameInfo.Alias != null) { return(NameGenerator.GetBaseNames(nameInfo.Alias)); } if (!IsValidType(nameInfo.Type)) { return(default);
public override async Task ProvideCompletionsAsync(CompletionContext completionContext) { try { var position = completionContext.Position; var document = completionContext.Document; var cancellationToken = completionContext.CancellationToken; var semanticModel = await document.GetSemanticModelForSpanAsync(new Text.TextSpan(position, 0), cancellationToken).ConfigureAwait(false); if (!completionContext.Options.GetOption(CompletionOptions.ShowNameSuggestions, LanguageNames.CSharp)) { return; } var context = CSharpSyntaxContext.CreateContext(document.Project.Solution.Workspace, semanticModel, position, cancellationToken); if (context.IsInNonUserCode) { return; } var nameInfo = await NameDeclarationInfo.GetDeclarationInfoAsync(document, position, cancellationToken).ConfigureAwait(false); var baseNames = GetBaseNames(semanticModel, nameInfo); if (baseNames == default) { return; } var recommendedNames = await GetRecommendedNamesAsync(baseNames, nameInfo, context, document, cancellationToken).ConfigureAwait(false); var sortValue = 0; foreach (var(name, kind) in recommendedNames) { // We've produced items in the desired order, add a sort text to each item to prevent alphabetization completionContext.AddItem(CreateCompletionItem(name, GetGlyph(kind, nameInfo.DeclaredAccessibility), sortValue.ToString("D8"))); sortValue++; } completionContext.SuggestionModeItem = CommonCompletionItem.Create( CSharpFeaturesResources.Name, displayTextSuffix: "", CompletionItemRules.Default); } catch (Exception e) when(FatalError.ReportWithoutCrashUnlessCanceled(e)) { // nop } }
private static bool IsTypeParameterDeclaration(SyntaxToken token, SemanticModel semanticModel, int position, CancellationToken cancellationToken, out NameDeclarationInfo result) { if (token.IsKind(SyntaxKind.LessThanToken, SyntaxKind.CommaToken) && token.Parent.IsKind(SyntaxKind.TypeParameterList)) { result = new NameDeclarationInfo( ImmutableArray.Create(SymbolKind.TypeParameter), Accessibility.NotApplicable, new DeclarationModifiers(), type: null); return(true); } result = default(NameDeclarationInfo); return(false); }
private static bool IsPossibleOutVariableDeclaration(SyntaxToken token, SemanticModel semanticModel, int position, ITypeInferenceService typeInferenceService, CancellationToken cancellationToken, out NameDeclarationInfo result) { if (!token.IsKind(SyntaxKind.IdentifierToken) || !(token.Parent.IsKind(SyntaxKind.IdentifierName))) { result = default; return(false); } var argument = token.Parent.Parent as ArgumentSyntax // var is child of ArgumentSyntax, eg. Goo(out var $$ ?? token.Parent.Parent.Parent as ArgumentSyntax; // var is child of DeclarationExpression // under ArgumentSyntax, eg. Goo(out var a$$ if (argument == null || !argument.RefOrOutKeyword.IsKind(SyntaxKind.OutKeyword)) { result = default; return(false); } var type = typeInferenceService.InferType(semanticModel, argument.SpanStart, objectAsDefault: false, cancellationToken: cancellationToken); if (type != null) { result = new NameDeclarationInfo( ImmutableArray.Create(SymbolKind.Local), Accessibility.NotApplicable, new DeclarationModifiers(), type, alias: null); return(true); } result = default; return(false); }
public override async Task ProvideCompletionsAsync(CompletionContext completionContext) { var position = completionContext.Position; var document = completionContext.Document; var cancellationToken = completionContext.CancellationToken; var semanticModel = await document.GetSemanticModelForSpanAsync(new Text.TextSpan(position, 0), cancellationToken).ConfigureAwait(false); var context = CSharpSyntaxContext.CreateContext(document.Project.Solution.Workspace, semanticModel, position, cancellationToken); if (context.IsInNonUserCode) { return; } var nameInfo = await NameDeclarationInfo.GetDeclarationInfo(document, position, cancellationToken).ConfigureAwait(false); if (!IsValidType(nameInfo.Type)) { return; } var type = UnwrapType(nameInfo.Type, semanticModel.Compilation); var baseNames = NameGenerator.GetBaseNames(type); var recommendedNames = await GetRecommendedNamesAsync(baseNames, nameInfo, context, document, cancellationToken).ConfigureAwait(false); int sortValue = 0; foreach (var(name, kind) in recommendedNames) { // We've produced items in the desired order, add a sort text to each item to prevent alphabetization completionContext.AddItem(CreateCompletionItem(name, GetGlyph(kind, nameInfo.DeclaredAccessibility), sortValue.ToString("D8"))); sortValue++; } completionContext.SuggestionModeItem = CommonCompletionItem.Create(CSharpFeaturesResources.Name, CompletionItemRules.Default); }
public override async Task ProvideCompletionsAsync(CompletionContext completionContext) { try { var position = completionContext.Position; var document = completionContext.Document; var cancellationToken = completionContext.CancellationToken; var semanticModel = await document.ReuseExistingSpeculativeModelAsync(position, cancellationToken).ConfigureAwait(false); if (!completionContext.CompletionOptions.ShowNameSuggestions) { return; } var context = CSharpSyntaxContext.CreateContext(document, semanticModel, position, cancellationToken); if (context.IsInNonUserCode) { return; } var nameInfo = await NameDeclarationInfo.GetDeclarationInfoAsync(document, position, cancellationToken).ConfigureAwait(false); using var _ = ArrayBuilder <(string name, SymbolKind kind)> .GetInstance(out var result); // Suggest names from existing overloads. if (nameInfo.PossibleSymbolKinds.Any(k => k.SymbolKind == SymbolKind.Parameter)) { var(_, partialSemanticModel) = await document.GetPartialSemanticModelAsync(cancellationToken).ConfigureAwait(false); if (partialSemanticModel is not null) { AddNamesFromExistingOverloads(context, partialSemanticModel, result, cancellationToken); } } var baseNames = GetBaseNames(semanticModel, nameInfo); if (baseNames != default) { await GetRecommendedNamesAsync(baseNames, nameInfo, context, document, result, cancellationToken).ConfigureAwait(false); } var recommendedNames = result.ToImmutable(); if (recommendedNames.IsEmpty) { return; } var sortValue = 0; foreach (var(name, kind) in recommendedNames) { // We've produced items in the desired order, add a sort text to each item to prevent alphabetization completionContext.AddItem(CreateCompletionItem(name, GetGlyph(kind, nameInfo.DeclaredAccessibility), sortValue.ToString("D8"))); sortValue++; } completionContext.SuggestionModeItem = CommonCompletionItem.Create( CSharpFeaturesResources.Name, displayTextSuffix: "", CompletionItemRules.Default); } catch (Exception e) when(FatalError.ReportAndCatchUnlessCanceled(e, ErrorSeverity.General)) { // nop } }
private static bool IsMethodDeclaration(SyntaxToken token, SemanticModel semanticModel, int position, CancellationToken cancellationToken, out NameDeclarationInfo result) { result = IsLastTokenOfType <MethodDeclarationSyntax>( token, semanticModel, m => m.ReturnType, m => m.Modifiers, GetPossibleDeclarations, cancellationToken); return(result.Type != null); }
private static bool IsParameterDeclaration(SyntaxToken token, SemanticModel semanticModel, int position, CancellationToken cancellationToken, out NameDeclarationInfo result) { result = IsLastTokenOfType <ParameterSyntax>( token, semanticModel, p => p.Type, _ => default(SyntaxTokenList), _ => ImmutableArray.Create(SymbolKind.Parameter), cancellationToken); return(result.Type != null); }
private static bool IsVariableDeclaration(SyntaxToken token, SemanticModel semanticModel, int position, CancellationToken cancellationToken, out NameDeclarationInfo result) { result = IsFollowingTypeOrComma <VariableDeclarationSyntax>(token, semanticModel, v => v.Type, v => v.Parent is LocalDeclarationStatementSyntax l ? l.Modifiers : default(SyntaxTokenList?), d => ImmutableArray.Create(SymbolKind.Local), cancellationToken); return(result.Type != null); }
private static bool IsIncompleteMemberDeclaration(SyntaxToken token, SemanticModel semanticModel, int position, CancellationToken cancellationToken, out NameDeclarationInfo result) { result = IsLastTokenOfType <IncompleteMemberSyntax>(token, semanticModel, i => i.Type, i => i.Modifiers, GetPossibleDeclarations, cancellationToken); return(result.Type != null); }
private static bool IsFieldDeclaration(SyntaxToken token, SemanticModel semanticModel, int position, CancellationToken cancellationToken, out NameDeclarationInfo result) { result = IsFollowingTypeOrComma <VariableDeclarationSyntax>(token, semanticModel, v => v.Type, v => v.Parent is FieldDeclarationSyntax f ? f.Modifiers : default(SyntaxTokenList?), GetPossibleDeclarations, cancellationToken); return(result.Type != null); }
public override async Task ProvideCompletionsAsync(CompletionContext completionContext) { try { var position = completionContext.Position; var document = completionContext.Document; var cancellationToken = completionContext.CancellationToken; if (!completionContext.CompletionOptions.ShowNameSuggestions) { return; } var context = (CSharpSyntaxContext)await completionContext.GetSyntaxContextWithExistingSpeculativeModelAsync(document, cancellationToken).ConfigureAwait(false); if (context.IsInNonUserCode) { return; } // Do not show name suggestions for unbound "async" identifier. // Most likely user is writing an async method, so name suggestion will just interfere him if (context.TargetToken.IsKindOrHasMatchingText(SyntaxKind.AsyncKeyword) && context.SemanticModel.GetSymbolInfo(context.TargetToken).GetAnySymbol() is null) { return; } var nameInfo = await NameDeclarationInfo.GetDeclarationInfoAsync(document, position, cancellationToken).ConfigureAwait(false); using var _ = ArrayBuilder <(string name, SymbolKind kind)> .GetInstance(out var result); // Suggest names from existing overloads. if (nameInfo.PossibleSymbolKinds.Any(k => k.SymbolKind == SymbolKind.Parameter)) { var(_, partialSemanticModel) = await document.GetPartialSemanticModelAsync(cancellationToken).ConfigureAwait(false); if (partialSemanticModel is not null) { AddNamesFromExistingOverloads(context, partialSemanticModel, result, cancellationToken); } } var baseNames = GetBaseNames(context.SemanticModel, nameInfo); if (baseNames != default) { var namingStyleOptions = await document.GetNamingStylePreferencesAsync(completionContext.CompletionOptions.NamingStyleFallbackOptions, cancellationToken).ConfigureAwait(false); GetRecommendedNames(baseNames, nameInfo, context, result, namingStyleOptions, cancellationToken); } var recommendedNames = result.ToImmutable(); if (recommendedNames.IsEmpty) { return; } var sortValue = 0; foreach (var(name, kind) in recommendedNames) { // We've produced items in the desired order, add a sort text to each item to prevent alphabetization completionContext.AddItem(CreateCompletionItem(name, GetGlyph(kind, nameInfo.DeclaredAccessibility), sortValue.ToString("D8"))); sortValue++; } completionContext.SuggestionModeItem = CommonCompletionItem.Create( CSharpFeaturesResources.Name, displayTextSuffix: "", CompletionItemRules.Default); } catch (Exception e) when(FatalError.ReportAndCatchUnlessCanceled(e, ErrorSeverity.General)) { // nop } }