/// <summary> /// Formats the whitespace of a syntax tree. /// </summary> /// <param name="node">The root node of a syntax tree to format.</param> /// <param name="options">An optional set of formatting options. If these options are not supplied the current set of options from the workspace will be used.</param> /// <param name="cancellationToken">An optional cancellation token.</param> /// <returns>The formatted tree's root node.</returns> public static SyntaxNode Format(SyntaxNode node, ISyntaxFormattingService syntaxFormattingService, OptionSet options, CancellationToken cancellationToken) => Format(node, syntaxFormattingService, SpecializedCollections.SingletonEnumerable(node.FullSpan), options, rules: null, cancellationToken: cancellationToken);
private static async Task <ImmutableArray <ReferenceLocationDescriptor> > FixUpDescriptorsAsync( Solution solution, ImmutableArray <ReferenceLocationDescriptor> descriptors, CancellationToken cancellationToken) { using var _ = ArrayBuilder <ReferenceLocationDescriptor> .GetInstance(out var list); foreach (var descriptor in descriptors) { var referencedDocumentId = DocumentId.CreateFromSerialized( ProjectId.CreateFromSerialized(descriptor.ProjectGuid), descriptor.DocumentGuid); var document = solution.GetDocument(referencedDocumentId); if (document == null) { continue; } var spanMapper = document.Services.GetService <ISpanMappingService>(); if (spanMapper == null) { // for normal document, just add one as they are list.Add(descriptor); continue; } var span = new TextSpan(descriptor.SpanStart, descriptor.SpanLength); var results = await spanMapper.MapSpansAsync(document, SpecializedCollections.SingletonEnumerable(span), cancellationToken).ConfigureAwait(false); // external component violated contracts. the mapper should preserve input order/count. // since we gave in 1 span, it should return 1 span back Contract.ThrowIfTrue(results.IsDefaultOrEmpty); var result = results[0]; if (result.IsDefault) { // it is allowed for mapper to return default // if it can't map the given span to any usable span continue; } var excerpter = document.Services.GetService <IDocumentExcerptService>(); if (excerpter == null) { continue; } var referenceExcerpt = await excerpter.TryExcerptAsync(document, span, ExcerptMode.SingleLine, cancellationToken).ConfigureAwait(false); var tooltipExcerpt = await excerpter.TryExcerptAsync(document, span, ExcerptMode.Tooltip, cancellationToken).ConfigureAwait(false); var(text, start, length) = GetReferenceInfo(referenceExcerpt, descriptor); var(before1, before2, after1, after2) = GetReferenceTexts(referenceExcerpt, tooltipExcerpt, descriptor); list.Add(new ReferenceLocationDescriptor( descriptor.LongDescription, descriptor.Language, descriptor.Glyph, result.Span.Start, result.Span.Length, result.LinePositionSpan.Start.Line, result.LinePositionSpan.Start.Character, descriptor.ProjectGuid, descriptor.DocumentGuid, result.FilePath, text, start, length, before1, before2, after1, after2)); } return(list.ToImmutable()); }
public static ComposableCatalog CreateAssemblyCatalog(Assembly assembly) { return(CreateAssemblyCatalog(SpecializedCollections.SingletonEnumerable(assembly))); }
protected override async Task <IEnumerable <CodeActionOperation> > ComputePreviewOperationsAsync(CancellationToken cancellationToken) { return(SpecializedCollections.SingletonEnumerable( new ApplyChangesOperation(await _createChangedSolutionAsync(cancellationToken).ConfigureAwait(false)))); }
protected override IEnumerable <AbstractFormattingRule> GetFormattingRules(Document document) { return(SpecializedCollections.SingletonEnumerable(new FormattingRule()).Concat(Formatter.GetDefaultFormattingRules(document))); }
internal override IEnumerable <Bucket> GetAll() { return(SpecializedCollections.SingletonEnumerable(this)); }
protected override Task <IEnumerable <ISymbol> > GetPreselectedSymbolsWorker(AbstractSyntaxContext context, int position, OptionSet options, CancellationToken cancellationToken) { var newExpression = this.GetObjectCreationNewExpression(context.SyntaxTree, position, cancellationToken); if (newExpression == null) { return(SpecializedTasks.EmptyEnumerable <ISymbol>()); } var typeInferenceService = context.GetLanguageService <ITypeInferenceService>(); var type = typeInferenceService.InferType( context.SemanticModel, position, objectAsDefault: false, cancellationToken: cancellationToken); // Unwrap an array type fully. We only want to offer the underlying element type in the // list of completion items. bool isArray = false; while (type is IArrayTypeSymbol) { isArray = true; type = ((IArrayTypeSymbol)type).ElementType; } if (type == null) { return(SpecializedTasks.EmptyEnumerable <ISymbol>()); } // Unwrap nullable if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) { type = type.GetTypeArguments().FirstOrDefault(); } if (type.SpecialType == SpecialType.System_Void) { return(SpecializedTasks.EmptyEnumerable <ISymbol>()); } if (type.ContainsAnonymousType()) { return(SpecializedTasks.EmptyEnumerable <ISymbol>()); } if (!type.CanBeReferencedByName) { return(SpecializedTasks.EmptyEnumerable <ISymbol>()); } // Normally the user can't say things like "new IList". Except for "IList[] x = new |". // In this case we do want to allow them to preselect certain types in the completion // list even if they can't new them directly. if (!isArray) { if (type.TypeKind == TypeKind.Interface || type.TypeKind == TypeKind.Pointer || type.TypeKind == TypeKind.Dynamic || type.IsAbstract) { return(SpecializedTasks.EmptyEnumerable <ISymbol>()); } if (type.TypeKind == TypeKind.TypeParameter && !((ITypeParameterSymbol)type).HasConstructorConstraint) { return(SpecializedTasks.EmptyEnumerable <ISymbol>()); } } if (!type.IsEditorBrowsable(options.GetOption(RecommendationOptions.HideAdvancedMembers, context.SemanticModel.Language), context.SemanticModel.Compilation)) { return(SpecializedTasks.EmptyEnumerable <ISymbol>()); } return(Task.FromResult(SpecializedCollections.SingletonEnumerable((ISymbol)type))); }
private static void ComputeDeclarations( SemanticModel model, ISymbol associatedSymbol, SyntaxNode node, Func <SyntaxNode, int?, bool> shouldSkip, bool getSymbol, ArrayBuilder <DeclarationInfo> builder, int?levelsToCompute, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (shouldSkip(node, levelsToCompute)) { return; } var newLevel = DecrementLevel(levelsToCompute); switch (node.Kind()) { case SyntaxKind.NamespaceDeclaration: { var ns = (NamespaceDeclarationSyntax)node; foreach (var decl in ns.Members) { ComputeDeclarations(model, associatedSymbol: null, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); } var declInfo = GetDeclarationInfo(model, node, getSymbol, cancellationToken); builder.Add(declInfo); NameSyntax name = ns.Name; INamespaceSymbol nsSymbol = declInfo.DeclaredSymbol as INamespaceSymbol; while (name.Kind() == SyntaxKind.QualifiedName) { name = ((QualifiedNameSyntax)name).Left; var declaredSymbol = getSymbol ? nsSymbol?.ContainingNamespace : null; builder.Add(new DeclarationInfo(name, ImmutableArray <SyntaxNode> .Empty, declaredSymbol)); nsSymbol = declaredSymbol; } return; } case SyntaxKind.ClassDeclaration: case SyntaxKind.StructDeclaration: case SyntaxKind.InterfaceDeclaration: case SyntaxKind.RecordDeclaration: { var t = (TypeDeclarationSyntax)node; foreach (var decl in t.Members) { ComputeDeclarations(model, associatedSymbol: null, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); } var attributes = GetAttributes(t.AttributeLists).Concat(GetTypeParameterListAttributes(t.TypeParameterList)); builder.Add(GetDeclarationInfo(model, node, getSymbol, attributes, cancellationToken)); return; } case SyntaxKind.EnumDeclaration: { var t = (EnumDeclarationSyntax)node; foreach (var decl in t.Members) { ComputeDeclarations(model, associatedSymbol: null, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); } var attributes = GetAttributes(t.AttributeLists); builder.Add(GetDeclarationInfo(model, node, getSymbol, attributes, cancellationToken)); return; } case SyntaxKind.EnumMemberDeclaration: { var t = (EnumMemberDeclarationSyntax)node; var attributes = GetAttributes(t.AttributeLists); var codeBlocks = SpecializedCollections.SingletonEnumerable(t.EqualsValue).Concat(attributes); builder.Add(GetDeclarationInfo(model, node, getSymbol, codeBlocks, cancellationToken)); return; } case SyntaxKind.DelegateDeclaration: { var t = (DelegateDeclarationSyntax)node; var attributes = GetAttributes(t.AttributeLists) .Concat(GetParameterListInitializersAndAttributes(t.ParameterList)) .Concat(GetTypeParameterListAttributes(t.TypeParameterList)); builder.Add(GetDeclarationInfo(model, node, getSymbol, attributes, cancellationToken)); return; } case SyntaxKind.EventDeclaration: { var t = (EventDeclarationSyntax)node; if (t.AccessorList != null) { foreach (var decl in t.AccessorList.Accessors) { ComputeDeclarations(model, associatedSymbol: null, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); } } var attributes = GetAttributes(t.AttributeLists); builder.Add(GetDeclarationInfo(model, node, getSymbol, attributes, cancellationToken)); return; } case SyntaxKind.EventFieldDeclaration: case SyntaxKind.FieldDeclaration: { var t = (BaseFieldDeclarationSyntax)node; var attributes = GetAttributes(t.AttributeLists); foreach (var decl in t.Declaration.Variables) { var codeBlocks = SpecializedCollections.SingletonEnumerable(decl.Initializer).Concat(attributes); builder.Add(GetDeclarationInfo(model, decl, getSymbol, codeBlocks, cancellationToken)); } return; } case SyntaxKind.ArrowExpressionClause: { // Arrow expression clause declares getter symbol for properties and indexers. if (node.Parent is BasePropertyDeclarationSyntax parentProperty) { builder.Add(GetExpressionBodyDeclarationInfo(parentProperty, (ArrowExpressionClauseSyntax)node, model, getSymbol, cancellationToken)); } return; } case SyntaxKind.PropertyDeclaration: { var t = (PropertyDeclarationSyntax)node; if (t.AccessorList != null) { foreach (var decl in t.AccessorList.Accessors) { ComputeDeclarations(model, associatedSymbol: null, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); } } if (t.ExpressionBody != null) { ComputeDeclarations(model, associatedSymbol: null, t.ExpressionBody, shouldSkip, getSymbol, builder, levelsToCompute, cancellationToken); } var attributes = GetAttributes(t.AttributeLists); var codeBlocks = SpecializedCollections.SingletonEnumerable(t.Initializer).Concat(attributes); builder.Add(GetDeclarationInfo(model, node, getSymbol, codeBlocks, cancellationToken)); return; } case SyntaxKind.IndexerDeclaration: { var t = (IndexerDeclarationSyntax)node; if (t.AccessorList != null) { foreach (var decl in t.AccessorList.Accessors) { ComputeDeclarations(model, associatedSymbol: null, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); } } if (t.ExpressionBody != null) { ComputeDeclarations(model, associatedSymbol: null, t.ExpressionBody, shouldSkip, getSymbol, builder, levelsToCompute, cancellationToken); } var codeBlocks = GetParameterListInitializersAndAttributes(t.ParameterList); var attributes = GetAttributes(t.AttributeLists); codeBlocks = codeBlocks.Concat(attributes); builder.Add(GetDeclarationInfo(model, node, getSymbol, codeBlocks, cancellationToken)); return; } case SyntaxKind.AddAccessorDeclaration: case SyntaxKind.RemoveAccessorDeclaration: case SyntaxKind.GetAccessorDeclaration: case SyntaxKind.SetAccessorDeclaration: case SyntaxKind.InitAccessorDeclaration: { var t = (AccessorDeclarationSyntax)node; var blocks = ArrayBuilder <SyntaxNode> .GetInstance(); blocks.AddIfNotNull(t.Body); blocks.AddIfNotNull(t.ExpressionBody); blocks.AddRange(GetAttributes(t.AttributeLists)); builder.Add(GetDeclarationInfo(model, node, getSymbol, blocks, cancellationToken)); blocks.Free(); return; } case SyntaxKind.ConstructorDeclaration: case SyntaxKind.ConversionOperatorDeclaration: case SyntaxKind.DestructorDeclaration: case SyntaxKind.MethodDeclaration: case SyntaxKind.OperatorDeclaration: { var t = (BaseMethodDeclarationSyntax)node; var codeBlocks = GetParameterListInitializersAndAttributes(t.ParameterList); codeBlocks = codeBlocks.Concat(t.Body); if (t is ConstructorDeclarationSyntax ctorDecl && ctorDecl.Initializer != null) { codeBlocks = codeBlocks.Concat(ctorDecl.Initializer); } var expressionBody = GetExpressionBodySyntax(t); if (expressionBody != null) { codeBlocks = codeBlocks.Concat(expressionBody); } codeBlocks = codeBlocks.Concat(GetAttributes(t.AttributeLists)); if (node is MethodDeclarationSyntax methodDecl && methodDecl.TypeParameterList != null) { codeBlocks = codeBlocks.Concat(GetTypeParameterListAttributes(methodDecl.TypeParameterList)); } builder.Add(GetDeclarationInfo(model, node, getSymbol, codeBlocks, cancellationToken)); return; } case SyntaxKind.CompilationUnit: { var t = (CompilationUnitSyntax)node; if (associatedSymbol is IMethodSymbol) { builder.Add(GetDeclarationInfo(model, node, getSymbol, new[] { t }, cancellationToken)); } else { foreach (var decl in t.Members) { ComputeDeclarations(model, associatedSymbol: null, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); } if (t.AttributeLists.Any()) { var attributes = GetAttributes(t.AttributeLists); builder.Add(GetDeclarationInfo(model, node, getSymbol: false, attributes, cancellationToken)); } } return; } default: return; } }
private void RaiseAnalyzerChangedWarning(ProjectId projectId, string analyzerPath) { var messageArguments = new string[] { analyzerPath }; if (DiagnosticData.TryCreate(_analyzerChangedRule, messageArguments, projectId, _workspace, out var diagnostic)) { _updateSource.UpdateDiagnosticsForProject(projectId, Tuple.Create(s_analyzerChangedErrorId, analyzerPath), SpecializedCollections.SingletonEnumerable(diagnostic)); } }
/// <summary> /// True if the given symbol declaration is fully analyzed for the given analyzer. /// </summary> public bool IsDeclarationComplete(ISymbol symbol, int declarationIndex, DiagnosticAnalyzer analyzer) { var analyzerState = GetAnalyzerState(analyzer); return(IsDeclarationComplete(symbol, declarationIndex, SpecializedCollections.SingletonEnumerable(analyzerState))); }
private static IEnumerable <SyntaxNode> GetParameterInitializersAndAttributes(ParameterSyntax parameter) => SpecializedCollections.SingletonEnumerable(parameter.Default).Concat(GetAttributes(parameter.AttributeLists));
internal static async Task GenerateAndVerifySourceAsync( string metadataSource, string symbolName, string projectLanguage, string expected, bool signaturesOnly = true, bool includeXmlDocComments = false, string languageVersion = null, string metadataLanguageVersion = null) { using var context = TestContext.Create(projectLanguage, SpecializedCollections.SingletonEnumerable(metadataSource), includeXmlDocComments, languageVersion: languageVersion, metadataLanguageVersion: metadataLanguageVersion); await context.GenerateAndVerifySourceAsync(symbolName, expected, signaturesOnly : signaturesOnly); }
public async Task <IEnumerable <AbstractCallFinder> > CreateFindersAsync( ISymbol symbol, Project project, CancellationToken cancellationToken ) { if ( symbol.Kind == SymbolKind.Property || symbol.Kind == SymbolKind.Event || symbol.Kind == SymbolKind.Method ) { var finders = new List <AbstractCallFinder>(); finders.Add(new MethodCallFinder(symbol, project.Id, _asyncListener, this)); if (symbol.IsVirtual || symbol.IsAbstract) { finders.Add( new OverridingMemberFinder(symbol, project.Id, _asyncListener, this) ); } var @overrides = await SymbolFinder .FindOverridesAsync( symbol, project.Solution, cancellationToken : cancellationToken ) .ConfigureAwait(false); if (overrides.Any()) { finders.Add(new CallToOverrideFinder(symbol, project.Id, _asyncListener, this)); } if (symbol.GetOverriddenMember() != null) { finders.Add( new BaseMemberFinder( symbol.GetOverriddenMember(), project.Id, _asyncListener, this ) ); } var implementedInterfaceMembers = await SymbolFinder .FindImplementedInterfaceMembersAsync( symbol, project.Solution, cancellationToken : cancellationToken ) .ConfigureAwait(false); foreach (var implementedInterfaceMember in implementedInterfaceMembers) { finders.Add( new InterfaceImplementationCallFinder( implementedInterfaceMember, project.Id, _asyncListener, this ) ); } if (symbol.IsImplementableMember()) { finders.Add(new ImplementerFinder(symbol, project.Id, _asyncListener, this)); } return(finders); } if (symbol.Kind == SymbolKind.Field) { return(SpecializedCollections.SingletonEnumerable( new FieldReferenceFinder(symbol, project.Id, _asyncListener, this) )); } return(null); }
private void Tracker_UpdatedOnDisk(object sender, EventArgs e) { FileChangeTracker tracker = (FileChangeTracker)sender; var filePath = tracker.FilePath; lock (_fileChangeTrackersLock) { // Once we've created a diagnostic for a given analyzer file, there's // no need to keep watching it. _fileChangeTrackers.Remove(filePath); } tracker.Dispose(); tracker.UpdatedOnDisk -= Tracker_UpdatedOnDisk; string id = ServicesVSResources.WRN_AnalyzerChangedId; string category = ServicesVSResources.ErrorCategory; string message = string.Format(ServicesVSResources.WRN_AnalyzerChangedMessage, filePath); // Traverse the chain of requesting assemblies to get back to the original analyzer // assembly. var assemblyPath = filePath; var requestingAssemblyPath = AnalyzerFileReference.TryGetRequestingAssemblyPath(filePath); while (requestingAssemblyPath != null) { assemblyPath = requestingAssemblyPath; requestingAssemblyPath = AnalyzerFileReference.TryGetRequestingAssemblyPath(assemblyPath); } var projectsWithAnalyzer = _workspace.ProjectTracker.Projects.Where(p => p.CurrentProjectAnalyzersContains(assemblyPath)).ToArray(); foreach (var project in projectsWithAnalyzer) { DiagnosticData data = new DiagnosticData( id, category, message, ServicesVSResources.WRN_AnalyzerChangedMessage, severity: DiagnosticSeverity.Warning, defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true, warningLevel: 0, customTags: ImmutableArray <string> .Empty, workspace: _workspace, projectId: project.Id); _updateSource.UpdateDiagnosticsForProject(project.Id, Tuple.Create(s_analyzerChangedErrorId, filePath), SpecializedCollections.SingletonEnumerable(data)); } }
public void TestP2PReference() { var workspace = new AdhocWorkspace(); var project1 = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Default, "proj1", "proj1", LanguageNames.CSharp); var project2 = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Default, "proj2", "proj2", LanguageNames.CSharp, projectReferences: SpecializedCollections.SingletonEnumerable(new ProjectReference(project1.Id))); var solutionInfo = SolutionInfo.Create(SolutionId.CreateNewId(), VersionStamp.Default, projects: new ProjectInfo[] { project1, project2 }); var solution = workspace.AddSolution(solutionInfo); var instanceTracker = ObjectReference.CreateFromFactory(() => new object()); var cacheService = new ProjectCacheService(workspace, int.MaxValue); using (var cache = cacheService.EnableCaching(project2.Id)) { instanceTracker.UseReference(r => cacheService.CacheObjectIfCachingEnabledForKey(project1.Id, (object)null, r)); solution = null; workspace.OnProjectRemoved(project1.Id); workspace.OnProjectRemoved(project2.Id); } // make sure p2p reference doesn't go to implicit cache instanceTracker.AssertReleased(); }
public AnalysisScope(ImmutableArray <DiagnosticAnalyzer> analyzers, SyntaxTree filterTree, TextSpan?filterSpan, bool syntaxAnalysis, bool concurrentAnalysis, bool categorizeDiagnostics) : this(SpecializedCollections.SingletonEnumerable(filterTree), analyzers, filterTree, filterSpan, syntaxAnalysis, concurrentAnalysis, categorizeDiagnostics) { Debug.Assert(filterTree != null); }
protected async Task TestPragmaOrAttributeAsync( string code, ParseOptions options, bool pragma, Func <SyntaxNode, bool> digInto, Func <string, bool> verifier, Func <CodeAction, bool> fixChecker) { using (var workspace = CreateWorkspaceFromFile(code, options)) { var document = workspace.CurrentSolution.Projects.Single().Documents.Single(); var root = document.GetSyntaxRootAsync().GetAwaiter().GetResult(); var existingDiagnostics = root.GetDiagnostics().ToArray(); var analyzerAndFixer = CreateDiagnosticProviderAndFixer(workspace); var analyzer = analyzerAndFixer.Item1; var fixer = analyzerAndFixer.Item2; var descendants = root.DescendantNodesAndSelf(digInto).ToImmutableArray(); analyzer.AllNodes = descendants; var diagnostics = await DiagnosticProviderTestUtilities.GetAllDiagnosticsAsync(analyzer, document, root.FullSpan); foreach (var diagnostic in diagnostics) { if (!fixer.CanBeSuppressedOrUnsuppressed(diagnostic)) { continue; } var fixes = fixer.GetSuppressionsAsync(document, diagnostic.Location.SourceSpan, SpecializedCollections.SingletonEnumerable(diagnostic), CancellationToken.None).GetAwaiter().GetResult(); if (fixes == null || fixes.Count() <= 0) { continue; } var fix = GetFix(fixes.Select(f => f.Action), pragma); if (fix == null) { continue; } // already same fix has been tested if (fixChecker(fix)) { continue; } var operations = fix.GetOperationsAsync(CancellationToken.None).GetAwaiter().GetResult(); var applyChangesOperation = operations.OfType <ApplyChangesOperation>().Single(); var newDocument = applyChangesOperation.ChangedSolution.Projects.Single().Documents.Single(); var newTree = newDocument.GetSyntaxTreeAsync().GetAwaiter().GetResult(); var newText = newTree.GetText().ToString(); Assert.True(verifier(newText)); var newDiagnostics = newTree.GetDiagnostics(); Assert.Equal(0, existingDiagnostics.Except(newDiagnostics, this).Count()); } } }
/// <summary> /// All fields should have already been added as synthesized members on the /// <see cref="CommonPEModuleBuilder" />, so we don't want to duplicate them here. /// </summary> internal override IEnumerable <FieldSymbol> GetFieldsToEmit() => (object)SingletonCache != null ? SpecializedCollections.SingletonEnumerable(SingletonCache) : SpecializedCollections.EmptyEnumerable <FieldSymbol>();
// Internal for testing purposes. internal DiagnosticAnalyzerService(string language, ImmutableArray <DiagnosticAnalyzer> analyzers) : this(ImmutableDictionary.CreateRange( SpecializedCollections.SingletonEnumerable(KeyValuePair.Create(language, analyzers)))) { }
public override async Task <CompletionList> GetCompletionsAsync( Document document, int caretPosition, CompletionTrigger trigger, ImmutableHashSet <string> roles, OptionSet options, CancellationToken cancellationToken) { var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); var defaultItemSpan = this.GetDefaultCompletionListSpan(text, caretPosition); options = options ?? document.Options; var providers = GetProviders(roles, trigger); var completionProviderToIndex = GetCompletionProviderToIndex(providers); var triggeredProviders = ImmutableArray <CompletionProvider> .Empty; switch (trigger.Kind) { case CompletionTriggerKind.Insertion: case CompletionTriggerKind.Deletion: if (this.ShouldTriggerCompletion(text, caretPosition, trigger, roles, options)) { triggeredProviders = providers.Where(p => p.ShouldTriggerCompletion(text, caretPosition, trigger, options)).ToImmutableArrayOrEmpty(); if (triggeredProviders.Length == 0) { triggeredProviders = providers; } } break; default: triggeredProviders = providers; break; } // Now, ask all the triggered providers if they can provide a group. var completionContexts = new List <CompletionContext>(); foreach (var provider in triggeredProviders) { var completionContext = await GetContextAsync( provider, document, caretPosition, trigger, options, defaultItemSpan, cancellationToken).ConfigureAwait(false); if (completionContext != null) { completionContexts.Add(completionContext); } } // See if there was a group provided that was exclusive and had items in it. If so, then // that's all we'll return. var firstExclusiveContext = completionContexts.FirstOrDefault(t => t.IsExclusive && t.Items.Any()); if (firstExclusiveContext != null) { return(MergeAndPruneCompletionLists( SpecializedCollections.SingletonEnumerable(firstExclusiveContext), defaultItemSpan, isExclusive: true)); } // If no exclusive providers provided anything, then go through the remaining // triggered list and see if any provide items. var nonExclusiveLists = completionContexts.Where(t => !t.IsExclusive).ToList(); // If we still don't have any items, then we're definitely done. if (!nonExclusiveLists.Any(g => g.Items.Any())) { return(null); } // If we do have items, then ask all the other (non exclusive providers) if they // want to augment the items. var usedProviders = nonExclusiveLists.Select(g => g.Provider); var nonUsedProviders = providers.Except(usedProviders); var nonUsedNonExclusiveLists = new List <CompletionContext>(); foreach (var provider in nonUsedProviders) { var completionList = await GetContextAsync(provider, document, caretPosition, trigger, options, defaultItemSpan, cancellationToken).ConfigureAwait(false); if (completionList != null && !completionList.IsExclusive) { nonUsedNonExclusiveLists.Add(completionList); } } var allProvidersAndLists = nonExclusiveLists.Concat(nonUsedNonExclusiveLists).ToList(); if (allProvidersAndLists.Count == 0) { return(null); } // Providers are ordered, but we processed them in our own order. Ensure that the // groups are properly ordered based on the original providers. allProvidersAndLists.Sort((p1, p2) => completionProviderToIndex[p1.Provider] - completionProviderToIndex[p2.Provider]); return(MergeAndPruneCompletionLists(allProvidersAndLists, defaultItemSpan, isExclusive: false)); }
public override async Task PostFomatPastedText(int insertionOffset, int insertedChars) { if (indent.Editor.Options.IndentStyle == IndentStyle.None || indent.Editor.Options.IndentStyle == IndentStyle.Auto) { return; } if (DefaultSourceEditorOptions.Instance.OnTheFlyFormatting) { var tree = await indent.DocumentContext.AnalysisDocument.GetSyntaxTreeAsync(); var startLine = indent.Editor.GetLineByOffset(insertionOffset); var endLine = indent.Editor.GetLineByOffset(insertionOffset + insertedChars); int lineStartOffset = startLine.Offset != endLine.Offset ? startLine.Offset : insertionOffset; int formatCharsCount = insertedChars + (insertionOffset - lineStartOffset); var policy = indent.DocumentContext.GetFormattingPolicy(); var textPolicy = indent.DocumentContext.Project.Policies.Get <Ide.Gui.Content.TextStylePolicy> (indent.Editor.MimeType); var optionSet = policy.CreateOptions(textPolicy); var span = new TextSpan(lineStartOffset, formatCharsCount); var rules = new List <IFormattingRule> () { new PasteFormattingRule() }; rules.AddRange(Formatter.GetDefaultFormattingRules(indent.DocumentContext.AnalysisDocument)); var root = tree.GetRoot(); var changes = Formatter.GetFormattedTextChanges(root, SpecializedCollections.SingletonEnumerable(span), indent.DocumentContext.RoslynWorkspace, optionSet, rules, default(CancellationToken)); indent.Editor.ApplyTextChanges(changes); return; } // Just correct the start line of the paste operation - the text is already indented. var curLine = indent.Editor.GetLineByOffset(insertionOffset); var curLineOffset = curLine.Offset; indent.SafeUpdateIndentEngine(curLineOffset); if (!indent.stateTracker.IsInsideOrdinaryCommentOrString) { int pos = curLineOffset; string curIndent = curLine.GetIndentation(indent.Editor); int nlwsp = curIndent.Length; if (!indent.stateTracker.LineBeganInsideMultiLineComment || (nlwsp < curLine.LengthIncludingDelimiter && indent.Editor.GetCharAt(curLineOffset + nlwsp) == '*')) { // Possibly replace the indent indent.SafeUpdateIndentEngine(curLineOffset + curLine.Length); string newIndent = indent.stateTracker.ThisLineIndent; if (newIndent != curIndent) { if (CompletionWindowManager.IsVisible) { if (pos < CompletionWindowManager.CodeCompletionContext.TriggerOffset) { CompletionWindowManager.CodeCompletionContext.TriggerOffset -= nlwsp; } } indent.Editor.ReplaceText(pos, nlwsp, newIndent); // textEditorData.Document.CommitLineUpdate (textEditorData.CaretLine); } } } indent.Editor.FixVirtualIndentation(); }
public async Task <SyntaxNode> CleanupAsync(SyntaxNode root, IEnumerable <TextSpan> spans, Workspace workspace, IEnumerable <ICodeCleanupProvider> providers, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.CodeCleanup_Cleanup, cancellationToken)) { // If there is no span to format... if (!spans.Any()) { // ... then return the Document unchanged return(root); } var codeCleaners = providers ?? GetDefaultProviders(); var normalizedSpan = spans.ToNormalizedSpans(); if (CleanupWholeNode(root.FullSpan, normalizedSpan)) { // We are cleaning up the whole document, so there is no need to do expansive span tracking between cleaners. return(await IterateAllCodeCleanupProvidersAsync(root, root, r => SpecializedCollections.SingletonEnumerable(r.FullSpan), workspace, codeCleaners, cancellationToken).ConfigureAwait(false)); } var syntaxFactsService = workspace.Services.GetLanguageServices(root.Language).GetService <ISyntaxFactsService>(); Contract.Requires(syntaxFactsService != null); // We need to track spans between cleaners. Annotate the tree with the provided spans. var newNodeAndAnnotations = AnnotateNodeForTextSpans(syntaxFactsService, root, normalizedSpan, cancellationToken); // If it urns out we don't need to annotate anything since all spans are merged to one span that covers the whole node... if (newNodeAndAnnotations.newNode == null) { // ... then we are cleaning up the whole document, so there is no need to do expansive span tracking between cleaners. return(await IterateAllCodeCleanupProvidersAsync(root, root, n => SpecializedCollections.SingletonEnumerable(n.FullSpan), workspace, codeCleaners, cancellationToken).ConfigureAwait(false)); } // Replace the initial node and document with the annotated node. var annotatedRoot = newNodeAndAnnotations.newNode; // Run the actual cleanup. return(await IterateAllCodeCleanupProvidersAsync( root, annotatedRoot, r => GetTextSpansFromAnnotation(r, newNodeAndAnnotations.annotations, cancellationToken), workspace, codeCleaners, cancellationToken).ConfigureAwait(false)); } }
private static IEnumerable <ModuleMetadata> EnumerateModules(Metadata metadata) { return((metadata.Kind == MetadataImageKind.Assembly) ? ((AssemblyMetadata)metadata).GetModules().AsEnumerable() : SpecializedCollections.SingletonEnumerable((ModuleMetadata)metadata)); }
public static ComposableCatalog WithoutPartsOfType(this ComposableCatalog catalog, Type t) => catalog.WithoutPartsOfTypes(SpecializedCollections.SingletonEnumerable(t));
private void OnDataBufferChanged(object sender, TextContentChangedEventArgs e) { // we don't actually care what has changed in primary buffer. we just want to re-analyze secondary buffer // when primary buffer has changed to update diagnostic positions. _diagnosticAnalyzerService.Reanalyze(this.Workspace, documentIds: SpecializedCollections.SingletonEnumerable(this.ContainedDocument.Id)); }
public static ComposableCatalog GetOrCreateAssemblyCatalog(Assembly assembly) => GetOrCreateAssemblyCatalog(SpecializedCollections.SingletonEnumerable(assembly));
public static ComposableCatalog WithPart(this ComposableCatalog catalog, Type t) { return(catalog.WithParts(CreateTypeCatalog(SpecializedCollections.SingletonEnumerable(t)))); }
/// <summary> /// Update the solution so that the document with the Id has the text changes /// </summary> internal static void ApplyTextChanges(this Workspace workspace, DocumentId id, TextChange textChange, CancellationToken cancellationToken) { workspace.ApplyTextChanges(id, SpecializedCollections.SingletonEnumerable(textChange), cancellationToken); }
public override async Task <CompletionList> GetCompletionsAsync( Document document, int caretPosition, CompletionTrigger trigger, ImmutableHashSet <string> roles, OptionSet options, CancellationToken cancellationToken) { var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); var defaultItemSpan = this.GetDefaultCompletionListSpan(text, caretPosition); options = options ?? await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); var providers = GetFilteredProviders(roles, trigger, options); var completionProviderToIndex = GetCompletionProviderToIndex(providers); var triggeredProviders = ImmutableArray <CompletionProvider> .Empty; switch (trigger.Kind) { case CompletionTriggerKind.Insertion: case CompletionTriggerKind.Deletion: if (this.ShouldTriggerCompletion(text, caretPosition, trigger, roles, options)) { triggeredProviders = providers.Where(p => p.ShouldTriggerCompletion(text, caretPosition, trigger, options)).ToImmutableArrayOrEmpty(); if (triggeredProviders.Length == 0) { triggeredProviders = providers; } } break; default: triggeredProviders = providers; break; } // Now, ask all the triggered providers, in parallel, to populate a completion context. // Note: we keep any context with items *or* with a suggested item. var triggeredCompletionContexts = await ComputeNonEmptyCompletionContextsAsync( document, caretPosition, trigger, options, defaultItemSpan, triggeredProviders, cancellationToken).ConfigureAwait(false); // If we didn't even get any back with items, then there's nothing to do. // i.e. if only got items back that had only suggestion items, then we don't // want to show any completion. if (!triggeredCompletionContexts.Any(cc => cc.Items.Count > 0)) { return(null); } // All the contexts should be non-empty or have a suggestion item. Debug.Assert(triggeredCompletionContexts.All(HasAnyItems)); // See if there was a completion context provided that was exclusive. If so, then // that's all we'll return. var firstExclusiveContext = triggeredCompletionContexts.FirstOrDefault(t => t.IsExclusive); if (firstExclusiveContext != null) { return(MergeAndPruneCompletionLists( SpecializedCollections.SingletonEnumerable(firstExclusiveContext), defaultItemSpan, isExclusive: true)); } // Shouldn't be any exclusive completion contexts at this point. Debug.Assert(triggeredCompletionContexts.All(cc => !cc.IsExclusive)); // Great! We had some items. Now we want to see if any of the other providers // would like to augment the completion list. For example, we might trigger // enum-completion on space. If enum completion results in any items, then // we'll want to augment the list with all the regular symbol completion items. var augmentingProviders = providers.Except(triggeredProviders).ToImmutableArray(); var augmentingCompletionContexts = await ComputeNonEmptyCompletionContextsAsync( document, caretPosition, trigger, options, defaultItemSpan, augmentingProviders, cancellationToken).ConfigureAwait(false); var allContexts = triggeredCompletionContexts.Concat(augmentingCompletionContexts); Debug.Assert(allContexts.Length > 0); // Providers are ordered, but we processed them in our own order. Ensure that the // groups are properly ordered based on the original providers. allContexts = allContexts.Sort((p1, p2) => completionProviderToIndex[p1.Provider] - completionProviderToIndex[p2.Provider]); return(MergeAndPruneCompletionLists(allContexts, defaultItemSpan, isExclusive: false)); }
/// <summary> /// Formats the whitespace in an area of a document corresponding to a text span. /// </summary> /// <param name="syntaxTree">The document to format.</param> /// <param name="span">The span of the document's text to format.</param> /// <param name="options">An optional set of formatting options. If these options are not supplied the current set of options from the document's workspace will be used.</param> /// <param name="cancellationToken">An optional cancellation token.</param> /// <returns>The formatted document.</returns> public static Task <SyntaxTree> FormatAsync(SyntaxTree syntaxTree, ISyntaxFormattingService syntaxFormattingService, TextSpan span, OptionSet options, CancellationToken cancellationToken) => FormatAsync(syntaxTree, syntaxFormattingService, SpecializedCollections.SingletonEnumerable(span), options, cancellationToken);