TestExportProvider.cs 8.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis.CodeGeneration;
using Microsoft.CodeAnalysis.Formatting;
using Microsoft.CodeAnalysis.Formatting.Rules;
using Microsoft.VisualStudio.Composition;
using Roslyn.Test.Utilities;

namespace Microsoft.CodeAnalysis.Editor.UnitTests
{
    /// <summary>
    /// This type caches MEF compositions for our unit tests.  MEF composition is a relatively expensive
    /// operation and caching yields demonstrable benefits for testing.
    /// 
    /// These caches must be done in a thread static manner.  Many of the stored values are non-frozen
    /// WPF elements which will throw if shared between threads.  It is legal for a given xUnit runner
    /// to execute classes on different threads hence we must handle this scenario.  
    /// </summary>
    public static class TestExportProvider
    {
        [ThreadStatic]
        private static Lazy<ComposableCatalog> t_lazyEntireAssemblyCatalogWithCSharpAndVisualBasic;

        public static ComposableCatalog EntireAssemblyCatalogWithCSharpAndVisualBasic
        {
            get
            {
                if (t_lazyEntireAssemblyCatalogWithCSharpAndVisualBasic == null)
                {
                    t_lazyEntireAssemblyCatalogWithCSharpAndVisualBasic = new Lazy<ComposableCatalog>(() => MinimalTestExportProvider.CreateAssemblyCatalog(GetNeutralAndCSharpAndVisualBasicTypes().Select(t => t.Assembly).Distinct().Concat(MinimalTestExportProvider.GetVisualStudioAssemblies())));
                }

                return t_lazyEntireAssemblyCatalogWithCSharpAndVisualBasic.Value;
            }
        }

        [ThreadStatic]
        private static Lazy<ExportProvider> t_lazyExportProviderWithCSharpAndVisualBasic;

        public static ExportProvider ExportProviderWithCSharpAndVisualBasic
        {
            get
            {
                if (t_lazyExportProviderWithCSharpAndVisualBasic == null)
                {
                    t_lazyExportProviderWithCSharpAndVisualBasic = new Lazy<ExportProvider>(CreateExportProviderWithCSharpAndVisualBasic);
                }

                return t_lazyExportProviderWithCSharpAndVisualBasic.Value;
            }
        }

        [ThreadStatic]
        private static Lazy<ComposableCatalog> t_lazyMinimumCatalogWithCSharpAndVisualBasic;

        public static ComposableCatalog MinimumCatalogWithCSharpAndVisualBasic
        {
            get
            {
                if (t_lazyMinimumCatalogWithCSharpAndVisualBasic == null)
                {
                    t_lazyMinimumCatalogWithCSharpAndVisualBasic = new Lazy<ComposableCatalog>(() => MinimalTestExportProvider.CreateTypeCatalog(GetNeutralAndCSharpAndVisualBasicTypes())
                        .WithParts(MinimalTestExportProvider.CreateAssemblyCatalog(MinimalTestExportProvider.GetVisualStudioAssemblies())));
                }

                return t_lazyMinimumCatalogWithCSharpAndVisualBasic.Value;
            }
        }

        private static Type[] GetNeutralAndCSharpAndVisualBasicTypes()
        {
            var types = new[]
            {
                // ROSLYN
                typeof(Workspaces.NoCompilationLanguageServiceFactory),
                typeof(Workspaces.NoCompilationContentTypeDefinitions),
                typeof(Workspaces.NoCompilationContentTypeLanguageService),
                typeof(Microsoft.CodeAnalysis.CSharp.IntroduceVariable.CSharpIntroduceVariableService), // Ensures that CSharpFeatures is included in the composition
                typeof(Microsoft.CodeAnalysis.VisualBasic.IntroduceVariable.VisualBasicIntroduceVariableService), // Ensures that BasicFeatures is included in the composition
                typeof(Microsoft.CodeAnalysis.Editor.CSharp.ContentType.ContentTypeDefinitions), // CSharp Content Type
                typeof(Microsoft.CodeAnalysis.Editor.VisualBasic.ContentType.ContentTypeDefinitions), // VB Content Type
                typeof(Microsoft.CodeAnalysis.Editor.Implementation.SmartIndent.SmartIndentProvider),
                typeof(Microsoft.CodeAnalysis.Editor.VisualBasic.Formatting.Indentation.VisualBasicIndentationService),
                typeof(Microsoft.CodeAnalysis.Editor.CSharp.Formatting.Indentation.CSharpIndentationService),
                typeof(Microsoft.CodeAnalysis.Editor.Implementation.ForegroundNotification.ForegroundNotificationService),
                typeof(Microsoft.CodeAnalysis.CSharp.CSharpCompilationFactoryService),
                typeof(Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilationFactoryService),
                typeof(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTreeFactoryServiceFactory), // CSharpServicesCore
                typeof(Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxTreeFactoryServiceFactory), // BasicServicesCore
                typeof(CodeAnalysis.CSharp.CodeGeneration.CSharpCodeGenerationServiceFactory),
                typeof(CodeAnalysis.VisualBasic.CodeGeneration.VisualBasicCodeGenerationServiceFactory),
                typeof(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxFactsService),
                typeof(Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxFactsService),
                typeof(CodeAnalysis.CSharp.CSharpSymbolDeclarationService),
                typeof(CodeAnalysis.VisualBasic.VisualBasicSymbolDeclarationService),
99 100
                typeof(CodeAnalysis.Editor.CSharp.LanguageServices.CSharpSymbolDisplayServiceFactory),
                typeof(CodeAnalysis.Editor.VisualBasic.LanguageServices.VisualBasicSymbolDisplayServiceFactory),
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
                typeof(CodeAnalysis.CSharp.Simplification.CSharpSimplificationService),
                typeof(CodeAnalysis.VisualBasic.Simplification.VisualBasicSimplificationService),
                typeof(CodeAnalysis.CSharp.Rename.CSharpRenameConflictLanguageService),
                typeof(CodeAnalysis.VisualBasic.Rename.VisualBasicRenameRewriterLanguageServiceFactory),
                typeof(CodeAnalysis.CSharp.CSharpSemanticFactsService),
                typeof(CodeAnalysis.VisualBasic.VisualBasicSemanticFactsService),
                typeof(CodeAnalysis.CSharp.CodeGeneration.CSharpSyntaxGenerator),
                typeof(CodeAnalysis.VisualBasic.CodeGeneration.VisualBasicSyntaxGenerator),
                typeof(CSharp.LanguageServices.CSharpContentTypeLanguageService),
                typeof(VisualBasic.LanguageServices.VisualBasicContentTypeLanguageService)
            };

            return MinimalTestExportProvider.GetLanguageNeutralTypes()
                .Concat(types)
                .Concat(TestHelpers.GetAllTypesImplementingGivenInterface(typeof(Microsoft.CodeAnalysis.CSharp.Formatting.DefaultOperationProvider).Assembly, typeof(ISyntaxFormattingService)))
                .Concat(TestHelpers.GetAllTypesImplementingGivenInterface(typeof(Microsoft.CodeAnalysis.VisualBasic.Formatting.DefaultOperationProvider).Assembly, typeof(ISyntaxFormattingService)))
                .Concat(TestHelpers.GetAllTypesImplementingGivenInterface(typeof(Microsoft.CodeAnalysis.CSharp.Formatting.DefaultOperationProvider).Assembly, typeof(IFormattingRule)))
                .Concat(TestHelpers.GetAllTypesImplementingGivenInterface(typeof(Microsoft.CodeAnalysis.VisualBasic.Formatting.DefaultOperationProvider).Assembly, typeof(IFormattingRule)))
                .Concat(TestHelpers.GetAllTypesImplementingGivenInterface(typeof(Microsoft.CodeAnalysis.CSharp.Formatting.DefaultOperationProvider).Assembly, typeof(ICodeGenerationService)))
                .Concat(TestHelpers.GetAllTypesImplementingGivenInterface(typeof(Microsoft.CodeAnalysis.VisualBasic.Formatting.DefaultOperationProvider).Assembly, typeof(ICodeGenerationService)))
                .Concat(TestHelpers.GetAllTypesWithStaticFieldsImplementingType(typeof(Microsoft.CodeAnalysis.CSharp.Formatting.CSharpFormattingOptions).Assembly, typeof(Microsoft.CodeAnalysis.Options.IOption)))
                .Distinct()
                .ToArray();
        }

        public static ExportProvider CreateExportProviderWithCSharpAndVisualBasic()
        {
            return MinimalTestExportProvider.CreateExportProvider(EntireAssemblyCatalogWithCSharpAndVisualBasic);
        }
    }
}