Exemple #1
0
 /// <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);
Exemple #2
0
        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))));
 }
Exemple #5
0
 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;
            }
        }
Exemple #9
0
        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));
            }
        }
Exemple #10
0
        /// <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);
 }
Exemple #13
0
        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);
        }
Exemple #14
0
        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));
            }
        }
Exemple #15
0
        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();
        }
Exemple #16
0
 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);
 }
Exemple #17
0
        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());
                }
            }
        }
Exemple #18
0
 /// <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>();
Exemple #19
0
 // 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));
        }
Exemple #21
0
        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));
            }
        }
Exemple #23
0
 private static IEnumerable <ModuleMetadata> EnumerateModules(Metadata metadata)
 {
     return((metadata.Kind == MetadataImageKind.Assembly) ? ((AssemblyMetadata)metadata).GetModules().AsEnumerable() : SpecializedCollections.SingletonEnumerable((ModuleMetadata)metadata));
 }
Exemple #24
0
 public static ComposableCatalog WithoutPartsOfType(this ComposableCatalog catalog, Type t)
 => catalog.WithoutPartsOfTypes(SpecializedCollections.SingletonEnumerable(t));
Exemple #25
0
 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));
 }
Exemple #26
0
 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))));
 }
Exemple #28
0
 /// <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));
        }
Exemple #30
0
 /// <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);