<commit_before>﻿// 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.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.CodeAnalysis.Test.Utilities.ComTypes;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;

namespace Microsoft.CodeAnalysis.Test.Utilities
{
    public static class CLRHelpers
    {
        private static readonly Guid s_clsIdClrRuntimeHost = new Guid("90F1A06E-7712-4762-86B5-7A5EBA6BDB02");
        private static readonly Guid s_clsIdCorMetaDataDispenser = new Guid("E5CB7A31-7512-11d2-89CE-0080C792E5D8");

        public static event ResolveEventHandler ReflectionOnlyAssemblyResolve;

        static CLRHelpers()
        {
            // Work around CLR bug: 
            // PE Verifier adds a handler to ReflectionOnlyAssemblyResolve event in AppDomain.EnableResolveAssembliesForIntrospection
            // (called from ValidateWorker in Validator.cpp) i nwhich it directly calls Assembly.ReflectionOnlyLoad.
            // If that happens before we get a chance to resolve the assembly the resolution fails.
            // 
            // The handlers are invoked in the order they were added until one of them returns non-null assembly.
            // Therefore once we call Validate we can't add any more handlers -- they would all follow the CLR one, which fails.
            // 
            // As A workaround we add a single forwarding handler before any calls to Validate and then subscribe all of our true handlers 
            // to this event. 
            AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += ReflectionOnlyAssemblyResolveHandler;
        }

        private static Assembly ReflectionOnlyAssemblyResolveHandler(object sender, ResolveEventArgs args)
        {
            var handler = ReflectionOnlyAssemblyResolve;
            if (handler != null)
            {
                return handler(sender, args);
            }

            return null;
        }

        public static bool IsRunningOnMono()
        {
            return Type.GetType ("Mono.Runtime") != null;
        }

        public static object GetRuntimeInterfaceAsObject(Guid clsid, Guid riid)
        {
            // This API isn't available on Mono hence we must use reflection to access it.  
            Debug.Assert(!IsRunningOnMono());

            var getRuntimeInterfaceAsObject = typeof(RuntimeEnvironment).GetMethod("GetRuntimeInterfaceasObject", BindingFlags.Public | BindingFlags.Static);
            return getRuntimeInterfaceAsObject.Invoke(null, new object[] { clsid, riid });
        }

        /// <summary>
        /// Verifies the specified image. Subscribe to <see cref="ReflectionOnlyAssemblyResolve"/> to provide a loader for dependent assemblies.
        /// </summary>
        public static string[] PeVerify(ImmutableArray<byte> peImage)
        {
            // fileName must be null, otherwise AssemblyResolve events won't fire
            return PeVerify(peImage.ToArray(), AppDomain.CurrentDomain.Id, assemblyPath: null);
        }

        /// <summary>
        /// Verifies the specified file. All dependencies must be on disk next to the file.
        /// </summary>
        public static string[] PeVerify(string filePath)
        {
            return PeVerify(File.ReadAllBytes(filePath), AppDomain.CurrentDomain.Id, filePath);
        }

        private static readonly object s_guard = new object();

        private static string[] PeVerify(byte[] peImage, int domainId, string assemblyPath)<commit_msg>Fix reflection call<commit_after>﻿// 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.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.CodeAnalysis.Test.Utilities.ComTypes;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;

namespace Microsoft.CodeAnalysis.Test.Utilities
{
    public static class CLRHelpers
    {
        private static readonly Guid s_clsIdClrRuntimeHost = new Guid("90F1A06E-7712-4762-86B5-7A5EBA6BDB02");
        private static readonly Guid s_clsIdCorMetaDataDispenser = new Guid("E5CB7A31-7512-11d2-89CE-0080C792E5D8");

        public static event ResolveEventHandler ReflectionOnlyAssemblyResolve;

        static CLRHelpers()
        {
            // Work around CLR bug: 
            // PE Verifier adds a handler to ReflectionOnlyAssemblyResolve event in AppDomain.EnableResolveAssembliesForIntrospection
            // (called from ValidateWorker in Validator.cpp) i nwhich it directly calls Assembly.ReflectionOnlyLoad.
            // If that happens before we get a chance to resolve the assembly the resolution fails.
            // 
            // The handlers are invoked in the order they were added until one of them returns non-null assembly.
            // Therefore once we call Validate we can't add any more handlers -- they would all follow the CLR one, which fails.
            // 
            // As A workaround we add a single forwarding handler before any calls to Validate and then subscribe all of our true handlers 
            // to this event. 
            AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += ReflectionOnlyAssemblyResolveHandler;
        }

        private static Assembly ReflectionOnlyAssemblyResolveHandler(object sender, ResolveEventArgs args)
        {
            var handler = ReflectionOnlyAssemblyResolve;
            if (handler != null)
            {
                return handler(sender, args);
            }

            return null;
        }

        public static bool IsRunningOnMono()
        {
            return Type.GetType ("Mono.Runtime") != null;
        }

        public static object GetRuntimeInterfaceAsObject(Guid clsid, Guid riid)
        {
            // This API isn't available on Mono hence we must use reflection to access it.  
            Debug.Assert(!IsRunningOnMono());

            var getRuntimeInterfaceAsObject = typeof(RuntimeEnvironment).GetMethod("GetRuntimeInterfaceAsObject", BindingFlags.Public | BindingFlags.Static);
            return getRuntimeInterfaceAsObject.Invoke(null, new object[] { clsid, riid });
        }

        /// <summary>
        /// Verifies the specified image. Subscribe to <see cref="ReflectionOnlyAssemblyResolve"/> to provide a loader for dependent assemblies.
        /// </summary>
        public static string[] PeVerify(ImmutableArray<byte> peImage)
        {
            // fileName must be null, otherwise AssemblyResolve events won't fire
            return PeVerify(peImage.ToArray(), AppDomain.CurrentDomain.Id, assemblyPath: null);
        }

        /// <summary>
        /// Verifies the specified file. All dependencies must be on disk next to the file.
        /// </summary>
        public static string[] PeVerify(string filePath)
        {
            return PeVerify(File.ReadAllBytes(filePath), AppDomain.CurrentDomain.Id, filePath);
        }

        private static readonly object s_guard = new object();

        private static string[] PeVerify(byte[] peImage, int domainId, string assemblyPath)
{'fraction_non_alphanumeric': 0.07288090837074201, 'fraction_numerical': 0.011882756799577503, 'mean_word_length': 2.6365818530964953, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2865194', 'n_tokens_mistral': 1911, 'n_tokens_neox': 1859, 'n_words': 629}