TestExportProvider.cs 9.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
// 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.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)
                {
32
                    t_lazyEntireAssemblyCatalogWithCSharpAndVisualBasic = new Lazy<ComposableCatalog>(() => CreateAssemblyCatalogWithCSharpAndVisualBasic());
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
                }

                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),
95
                typeof(Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxFactsServiceFactory),
96 97
                typeof(CodeAnalysis.CSharp.CSharpSymbolDeclarationService),
                typeof(CodeAnalysis.VisualBasic.VisualBasicSymbolDeclarationService),
98
                typeof(CodeAnalysis.Editor.CSharp.LanguageServices.CSharpSymbolDisplayServiceFactory),
99
                typeof(Microsoft.CodeAnalysis.Editor.CSharp.Interactive.CSharpInteractiveEvaluator),
100
                typeof(CodeAnalysis.Editor.VisualBasic.LanguageServices.VisualBasicSymbolDisplayServiceFactory),
101
                typeof(Microsoft.CodeAnalysis.Editor.VisualBasic.Interactive.VisualBasicInteractiveEvaluator),
102 103 104 105 106 107 108 109 110
                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),
C
Cyrus Najmabadi 已提交
111 112
                typeof(VisualBasic.LanguageServices.VisualBasicContentTypeLanguageService),
                typeof(IncrementalCaches.SymbolTreeInfoIncrementalAnalyzerProvider),
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
            };

            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();
        }

128 129 130 131
        /// <summary>
        /// Create fresh ExportProvider that doesnt share anything with others. 
        /// test can use this export provider to create all new MEF components not shared with others.
        /// </summary>
132 133
        public static ExportProvider CreateExportProviderWithCSharpAndVisualBasic()
        {
134 135 136 137 138 139 140 141 142 143 144 145
            return MinimalTestExportProvider.CreateExportProvider(CreateAssemblyCatalogWithCSharpAndVisualBasic());
        }

        /// <summary>
        /// Create fresh ComposableCatalog that doesnt share anything with others.
        /// everything under this catalog should have been created from scratch that doesnt share anything with others.
        /// </summary>
        public static ComposableCatalog CreateAssemblyCatalogWithCSharpAndVisualBasic()
        {
            return MinimalTestExportProvider.CreateAssemblyCatalog(
                GetNeutralAndCSharpAndVisualBasicTypes().Select(t => t.Assembly).Distinct().Concat(MinimalTestExportProvider.GetVisualStudioAssemblies()),
                MinimalTestExportProvider.CreateResolver());
146 147 148
        }
    }
}