TargetFrameworkUtil.cs 10.2 KB
Newer Older
J
Jared Parsons 已提交
1 2 3 4 5 6 7
// 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.Collections.Immutable;
using System.Text;
using Microsoft.CodeAnalysis;
J
Jared Parsons 已提交
8
using Microsoft.CodeAnalysis.Test.Utilities;
J
Jared Parsons 已提交
9 10 11 12 13 14 15 16 17
using static TestReferences;

namespace Roslyn.Test.Utilities
{
    public enum TargetFramework
    {
        /// <summary>
        /// Explicit pick a target framework that has no references
        /// </summary>
J
Jared Parsons 已提交
18
        Empty,
J
Jared Parsons 已提交
19 20

        NetStandard20,
J
Jared Parsons 已提交
21
        WinRT,
J
Jared Parsons 已提交
22 23 24 25 26

        /// <summary>
        /// Eventually this will be deleted and replaced with NetStandard20. Short term this creates the "standard"
        /// API set across destkop and coreclr 
        /// </summary>
J
Jared Parsons 已提交
27
        Standard,
J
Jared Parsons 已提交
28
        StandardAndCSharp,
J
Jared Parsons 已提交
29

30 31
        StandardAndVBRuntime,

J
Jared Parsons 已提交
32 33 34 35
        /// <summary>
        /// This is represents the set of tests which must be mscorlib40 on desktop but full net standard on coreclr.
        /// </summary>
        StandardCompat,
D
dotnet-bot 已提交
36

J
Jared Parsons 已提交
37 38 39 40
        /// <summary>
        /// Compat framework for the default set of references many vb compilations get.
        /// </summary>
        DefaultVb,
J
Jared Parsons 已提交
41 42 43

        // The flavors of mscorlib we support + extending them with LINQ and dynamic.
        Mscorlib40,
D
dotnet-bot 已提交
44
        Mscorlib40Extended,
J
Jared Parsons 已提交
45
        Mscorlib40AndSystemCore,
46
        Mscorlib40AndVBRuntime,
J
Jared Parsons 已提交
47 48
        Mscorlib45,
        Mscorlib45Extended,
J
Jared Parsons 已提交
49
        Mscorlib45AndCSharp,
50
        Mscorlib45AndVBRuntime,
J
Jared Parsons 已提交
51 52
        Mscorlib46,
        Mscorlib46Extended,
J
Jared Parsons 已提交
53 54
        Mscorlib461,
        Mscorlib461Extended,
J
Jared Parsons 已提交
55 56 57 58
    }

    public static class TargetFrameworkUtil
    {
J
Jared Parsons 已提交
59
        public static MetadataReference StandardCSharpReference => RuntimeUtilities.IsCoreClrRuntime ? NetStandard20.MicrosoftCSharpRef : TestBase.CSharpDesktopRef;
J
Jared Parsons 已提交
60

61 62 63 64 65 66 67
        /*
         * ⚠ Dev note ⚠: properties in TestBase are backed by Lazy<T>. Avoid changes to the following properties
         * which would force the initialization of these properties in the static constructor, since the stack traces
         * for a TypeLoadException are missing important information for resolving problems if/when they occur.
         * https://github.com/dotnet/roslyn/issues/25961
         */

68 69 70
        public static ImmutableArray<MetadataReference> Mscorlib40References => ImmutableArray.Create(TestBase.MscorlibRef);
        public static ImmutableArray<MetadataReference> Mscorlib40ExtendedReferences => ImmutableArray.Create(TestBase.MscorlibRef, TestBase.SystemRef, TestBase.SystemCoreRef, TestBase.ValueTupleRef, TestBase.SystemRuntimeFacadeRef);
        public static ImmutableArray<MetadataReference> Mscorlib40andSystemCoreReferences => ImmutableArray.Create(TestBase.MscorlibRef, TestBase.SystemCoreRef);
J
Jared Parsons 已提交
71
        public static ImmutableArray<MetadataReference> Mscorlib40andVBRuntimeReferences => ImmutableArray.Create(TestBase.MscorlibRef, TestBase.SystemRef, TestBase.MsvbRef);
72
        public static ImmutableArray<MetadataReference> Mscorlib45References => ImmutableArray.Create(TestBase.MscorlibRef_v4_0_30316_17626);
J
Jared Parsons 已提交
73 74
        public static ImmutableArray<MetadataReference> Mscorlib45ExtendedReferences => ImmutableArray.Create(TestBase.MscorlibRef_v4_0_30316_17626, TestBase.SystemRef, TestBase.SystemCoreRef_v4_0_30319_17929, TestBase.ValueTupleRef, TestBase.SystemRuntimeFacadeRef);
        public static ImmutableArray<MetadataReference> Mscorlib45AndCSharpReferences => ImmutableArray.Create(TestBase.MscorlibRef_v4_0_30316_17626, TestBase.SystemCoreRef_v4_0_30319_17929, TestBase.CSharpRef);
J
Jared Parsons 已提交
75
        public static ImmutableArray<MetadataReference> Mscorlib45AndVBRuntimeReferences => ImmutableArray.Create(TestBase.MscorlibRef_v4_0_30316_17626, TestBase.SystemRef, TestBase.MsvbRef_v4_0_30319_17929);
76 77
        public static ImmutableArray<MetadataReference> Mscorlib46References => ImmutableArray.Create(TestBase.MscorlibRef_v46);
        public static ImmutableArray<MetadataReference> Mscorlib46ExtendedReferences => ImmutableArray.Create(TestBase.MscorlibRef_v46, TestBase.SystemRef_v46, TestBase.SystemCoreRef_v46, TestBase.ValueTupleRef, TestBase.SystemRuntimeFacadeRef);
J
Jared Parsons 已提交
78 79
        public static ImmutableArray<MetadataReference> Mscorlib461References => ImmutableArray.Create<MetadataReference>(Net461.mscorlibRef);
        public static ImmutableArray<MetadataReference> Mscorlib461ExtendedReferences => ImmutableArray.Create<MetadataReference>(Net461.mscorlibRef, Net461.SystemRef, Net461.SystemCoreRef, Net461.SystemValueTupleRef, Net461.SystemRuntimeRef);
80 81
        public static ImmutableArray<MetadataReference> NetStandard20References => ImmutableArray.Create<MetadataReference>(NetStandard20.NetStandard, NetStandard20.MscorlibRef, NetStandard20.SystemRuntimeRef, NetStandard20.SystemCoreRef, NetStandard20.SystemDynamicRuntimeRef);
        public static ImmutableArray<MetadataReference> WinRTReferences => ImmutableArray.Create(TestBase.WinRtRefs);
J
Jared Parsons 已提交
82
        public static ImmutableArray<MetadataReference> StandardReferences => RuntimeUtilities.IsCoreClrRuntime ? NetStandard20References : Mscorlib46ExtendedReferences;
83
        public static ImmutableArray<MetadataReference> StandardAndCSharpReferences => StandardReferences.Add(StandardCSharpReference);
J
Jared Parsons 已提交
84 85
        public static ImmutableArray<MetadataReference> StandardAndVBRuntimeReferences => RuntimeUtilities.IsCoreClrRuntime ? NetStandard20References.Add(NetStandard20.MicrosoftVisualBasicRef) : Mscorlib46ExtendedReferences.Add(TestBase.MsvbRef_v4_0_30319_17929);
        public static ImmutableArray<MetadataReference> StandardCompatReferences => RuntimeUtilities.IsCoreClrRuntime ? NetStandard20References : Mscorlib40References;
J
Jared Parsons 已提交
86
        public static ImmutableArray<MetadataReference> DefaultVbReferencs => ImmutableArray.Create(TestBase.MscorlibRef, TestBase.SystemRef, TestBase.SystemCoreRef, TestBase.MsvbRef);
J
Jared Parsons 已提交
87

J
Jared Parsons 已提交
88 89 90 91
        public static ImmutableArray<MetadataReference> GetReferences(TargetFramework tf)
        {
            switch (tf)
            {
J
Jared Parsons 已提交
92
                case TargetFramework.Empty: return ImmutableArray<MetadataReference>.Empty;
J
Jared Parsons 已提交
93 94
                case TargetFramework.Mscorlib40: return Mscorlib40References;
                case TargetFramework.Mscorlib40Extended: return Mscorlib40ExtendedReferences;
J
Jared Parsons 已提交
95
                case TargetFramework.Mscorlib40AndSystemCore: return Mscorlib40andSystemCoreReferences;
96
                case TargetFramework.Mscorlib40AndVBRuntime: return Mscorlib40andVBRuntimeReferences;
J
Jared Parsons 已提交
97 98
                case TargetFramework.Mscorlib45: return Mscorlib45References;
                case TargetFramework.Mscorlib45Extended: return Mscorlib45ExtendedReferences;
J
Jared Parsons 已提交
99
                case TargetFramework.Mscorlib45AndCSharp: return Mscorlib45AndCSharpReferences;
100
                case TargetFramework.Mscorlib45AndVBRuntime: return Mscorlib45AndVBRuntimeReferences;
J
Jared Parsons 已提交
101 102
                case TargetFramework.Mscorlib46: return Mscorlib46References;
                case TargetFramework.Mscorlib46Extended: return Mscorlib46ExtendedReferences;
J
Jared Parsons 已提交
103 104
                case TargetFramework.Mscorlib461: return Mscorlib46References;
                case TargetFramework.Mscorlib461Extended: return Mscorlib461ExtendedReferences;
J
Jared Parsons 已提交
105
                case TargetFramework.NetStandard20: return NetStandard20References;
J
Jared Parsons 已提交
106
                case TargetFramework.WinRT: return WinRTReferences;
J
Jared Parsons 已提交
107
                case TargetFramework.Standard: return StandardReferences;
J
Jared Parsons 已提交
108
                case TargetFramework.StandardAndCSharp: return StandardAndCSharpReferences;
109
                case TargetFramework.StandardAndVBRuntime: return StandardAndVBRuntimeReferences;
J
Jared Parsons 已提交
110
                case TargetFramework.StandardCompat: return StandardCompatReferences;
J
Jared Parsons 已提交
111
                case TargetFramework.DefaultVb: return DefaultVbReferencs;
J
Jared Parsons 已提交
112 113 114 115 116 117 118 119 120 121 122 123
                default: throw new InvalidOperationException($"Unexpected target framework {tf}");
            }
        }

        public static ImmutableArray<MetadataReference> GetReferences(TargetFramework tf, IEnumerable<MetadataReference> additionalReferences)
        {
            var references = GetReferences(tf);
            if (additionalReferences == null)
            {
                return references;
            }

J
Jared Parsons 已提交
124 125 126
            checkForDuplicateReferences();
            return references.AddRange(additionalReferences);

J
Jared Parsons 已提交
127 128 129
            // Check to see if there are any duplicate references. This guards against tests inadvertently passing multiple copies of 
            // say System.Core to the tests and implicitly depending on the higher one to win. The few tests which actually mean to 
            // pass multiple verisons of a DLL should manually construct the reference list and not use this helper.
J
Jared Parsons 已提交
130
            void checkForDuplicateReferences()
J
Jared Parsons 已提交
131
            {
J
Jared Parsons 已提交
132 133
                var nameSet = new HashSet<string>(getNames(references), StringComparer.OrdinalIgnoreCase);
                foreach (var r in additionalReferences)
J
Jared Parsons 已提交
134
                {
J
Jared Parsons 已提交
135 136 137 138 139 140 141 142 143 144
                    if (references.Contains(r))
                    {
                        throw new Exception($"Duplicate reference detected {r.Display}");
                    }

                    var name = getName(r);
                    if (name != null && !nameSet.Add(name))
                    {
                        throw new Exception($"Duplicate reference detected {r.Display} - {name}");
                    }
J
Jared Parsons 已提交
145 146 147
                }
            }

D
dotnet-bot 已提交
148
            IEnumerable<string> getNames(IEnumerable<MetadataReference> e)
J
Jared Parsons 已提交
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
            {
                foreach (var r in e)
                {
                    var name = getName(r);
                    if (name != null)
                    {
                        yield return name;
                    }
                }
            }

            string getName(MetadataReference m)
            {
                if (m is PortableExecutableReference p &&
                    p.GetMetadata() is AssemblyMetadata assemblyMetadata)
                {
                    try
                    {
                        var identity = assemblyMetadata.GetAssembly().Identity;
                        return identity?.Name;
                    }
                    catch (BadImageFormatException)
                    {
                        // Happens when a native image is incorrectly passed as a PE.
                        return null;
                    }
                }

                return null;
            }
J
Jared Parsons 已提交
179 180 181
        }
    }
}