<commit_before>#region License
//-----------------------------------------------------------------------
// <copyright>
// The MIT License (MIT)
// 
// Copyright (c) 2014 <NAME>
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
//-----------------------------------------------------------------------
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using TypeInfo = Microsoft.CodeAnalysis.TypeInfo;

namespace WootzJs.Compiler
{
    public static class RoslynExtensions
    {
        public static string GetFullName(this TypeInfo typeInfo)
        {
            return typeInfo.ConvertedType.GetFullName();
        }

        public static string GetFullName(this INamespaceSymbol namespaceSymbol)
        {
            string result = namespaceSymbol.MetadataName;
            if (!namespaceSymbol.IsGlobalNamespace && !namespaceSymbol.ContainingNamespace.IsGlobalNamespace)
                result = namespaceSymbol.ContainingNamespace.GetFullName() + "." + result;
            return result;
        }

        public static string GetFullName(this ITypeSymbol type)
        {
            if (type.IsAnonymousType)
            {
                return type.GetTypeName();
            }
            if (type is IArrayTypeSymbol)
            {
                var arrayType = (IArrayTypeSymbol)type;
                return arrayType.ElementType.GetFullName() + "[]";
            }

            var typeParameter = type as ITypeParameterSymbol;
            if (typeParameter != null)
            {
                return typeParameter.Name;
            }
            else
            {
                string result = type.MetadataName;
                if (type.ContainingType != null)
                    result = type.ContainingType.GetFullName() + "." + result;
                else if (!type.ContainingNamespace.IsGlobalNamespace)
                    result = type.ContainingNamespace.GetFullName() + "." + result;
                return result;
            }
        }

        public static bool IsAssignableFrom(this ITypeSymbol baseType, ITypeSymbol type)
        {
            var current = type;
            while (current != null)
            {
                if (Equals(current, baseType))
                    return true;
                current = current.BaseType;
            }
            foreach (var intf in type.AllInterfaces)
            {
                if (Equals(intf, baseType))
                    return true;
            }
            return false;
        }

        public static bool IsSubclassOf(this ITypeSymbol @class, ITypeSymbol baseClass) 
        {
            var current = @class.BaseType;
            while (current != null)
            {
                if (Equals(current, baseClass))
                    return true;
                current = current.BaseType;
            }
            return false;
        }

        public static ITypeSymbol GetGenericArgument(this ITypeSymbol type, ITypeSymbol unconstructedType, int argumentIndex)
        {
            var current = type;
            while (current != null)
            {
                if (Equals(current.OriginalDefinition, unconstructedType))
                {
                    return ((INamedTypeSymbol)current).TypeArguments[argumentIndex];
                }
                current = current.BaseType;
            }
            if (type is INamedTypeSymbol)
            {
                var namedTypeSymbol = (INamedTypeSymbol)type;
                foreach (var intf in namedTypeSymbol.AllInterfaces)
                {
                    if (Equals(intf.OriginalDefinition, unconstructedType))
                    {
                        return intf.TypeArguments[argumentIndex];
                    }
                }
            }
            return null;
        }

        public static T GetAttributeValue<T>(this ISymbol symbol, INamedTypeSymbol attributeType, string propertyName, T defaultValue = default(T))
        {
            var jsAttributes = symbol.GetAttributes().Where(x => Equals(x.AttributeClass, attributeType)).ToArray();
            foreach (var jsAttribute in jsAttributes)
            {
                var argument = jsAttribute.NamedArguments.SingleOrDefault(x => x.Key == propertyName);
                if (argument.Value.Kind == TypedConstantKind.Array)
                {
                    var elementType = typeof(T).GetElementType();
                    var source = argument.Value.Values.Select(x => x.Value).ToArray();
                    var array = Array.CreateInstance(elementType, source.Length);
                    source.CopyTo(array, 0);
                    return (T)(object)array;
                }
                else
                {
                    if (argument.Value.Value != null)
                    {
                        return (T)argument.Value.Value;
                    }                    
                }
            }
            return defaultValue;
        }

        public static int GetBaseMemberNameCount(this INamedTypeSymbol type, string name)
        {
            if (type.BaseType != null)
                return type.BaseType.GetMemberNameCount(name);
            else
                return 0;
        }

        public static int GetMemberNameCount(this INamedTypeSymbol type, string name)
        {
            var count = 0;
            if (type.DeclaringSyntaxReferences.Any())
            {
                if (type.GetMembers(name).Any())
                    count++;
            }
            else
            {
                throw new Exception("This exception happens because we can't find the referenced project.  All project references should be true project references and not assembly references.  This is because we need all symbol information to be available when deriving JS symbol names.  When using dll references all non-public symbols will be missing.");
                var reflectedType = Context.Instance.ReflectionCache.GetReflectedType(type);
                if (reflectedType != null && reflectedType.GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance).Any(x => x.Name == name))<commit_msg>Add better diagnostics for missing type<commit_after>#region License
//-----------------------------------------------------------------------
// <copyright>
// The MIT License (MIT)
// 
// Copyright (c) 2014 <NAME>
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
//-----------------------------------------------------------------------
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using TypeInfo = Microsoft.CodeAnalysis.TypeInfo;

namespace WootzJs.Compiler
{
    public static class RoslynExtensions
    {
        public static string GetFullName(this TypeInfo typeInfo)
        {
            return typeInfo.ConvertedType.GetFullName();
        }

        public static string GetFullName(this INamespaceSymbol namespaceSymbol)
        {
            string result = namespaceSymbol.MetadataName;
            if (!namespaceSymbol.IsGlobalNamespace && !namespaceSymbol.ContainingNamespace.IsGlobalNamespace)
                result = namespaceSymbol.ContainingNamespace.GetFullName() + "." + result;
            return result;
        }

        public static string GetFullName(this ITypeSymbol type)
        {
            if (type.IsAnonymousType)
            {
                return type.GetTypeName();
            }
            if (type is IArrayTypeSymbol)
            {
                var arrayType = (IArrayTypeSymbol)type;
                return arrayType.ElementType.GetFullName() + "[]";
            }

            var typeParameter = type as ITypeParameterSymbol;
            if (typeParameter != null)
            {
                return typeParameter.Name;
            }
            else
            {
                string result = type.MetadataName;
                if (type.ContainingType != null)
                    result = type.ContainingType.GetFullName() + "." + result;
                else if (!type.ContainingNamespace.IsGlobalNamespace)
                    result = type.ContainingNamespace.GetFullName() + "." + result;
                return result;
            }
        }

        public static bool IsAssignableFrom(this ITypeSymbol baseType, ITypeSymbol type)
        {
            var current = type;
            while (current != null)
            {
                if (Equals(current, baseType))
                    return true;
                current = current.BaseType;
            }
            foreach (var intf in type.AllInterfaces)
            {
                if (Equals(intf, baseType))
                    return true;
            }
            return false;
        }

        public static bool IsSubclassOf(this ITypeSymbol @class, ITypeSymbol baseClass) 
        {
            var current = @class.BaseType;
            while (current != null)
            {
                if (Equals(current, baseClass))
                    return true;
                current = current.BaseType;
            }
            return false;
        }

        public static ITypeSymbol GetGenericArgument(this ITypeSymbol type, ITypeSymbol unconstructedType, int argumentIndex)
        {
            var current = type;
            while (current != null)
            {
                if (Equals(current.OriginalDefinition, unconstructedType))
                {
                    return ((INamedTypeSymbol)current).TypeArguments[argumentIndex];
                }
                current = current.BaseType;
            }
            if (type is INamedTypeSymbol)
            {
                var namedTypeSymbol = (INamedTypeSymbol)type;
                foreach (var intf in namedTypeSymbol.AllInterfaces)
                {
                    if (Equals(intf.OriginalDefinition, unconstructedType))
                    {
                        return intf.TypeArguments[argumentIndex];
                    }
                }
            }
            return null;
        }

        public static T GetAttributeValue<T>(this ISymbol symbol, INamedTypeSymbol attributeType, string propertyName, T defaultValue = default(T))
        {
            var jsAttributes = symbol.GetAttributes().Where(x => Equals(x.AttributeClass, attributeType)).ToArray();
            foreach (var jsAttribute in jsAttributes)
            {
                var argument = jsAttribute.NamedArguments.SingleOrDefault(x => x.Key == propertyName);
                if (argument.Value.Kind == TypedConstantKind.Array)
                {
                    var elementType = typeof(T).GetElementType();
                    var source = argument.Value.Values.Select(x => x.Value).ToArray();
                    var array = Array.CreateInstance(elementType, source.Length);
                    source.CopyTo(array, 0);
                    return (T)(object)array;
                }
                else
                {
                    if (argument.Value.Value != null)
                    {
                        return (T)argument.Value.Value;
                    }                    
                }
            }
            return defaultValue;
        }

        public static int GetBaseMemberNameCount(this INamedTypeSymbol type, string name)
        {
            if (type.BaseType != null)
                return type.BaseType.GetMemberNameCount(name);
            else
                return 0;
        }

        public static int GetMemberNameCount(this INamedTypeSymbol type, string name)
        {
            var count = 0;
            if (type.DeclaringSyntaxReferences.Any())
            {
                if (type.GetMembers(name).Any())
                    count++;
            }
            else
            {
                throw new Exception("This exception happens because we can't find the referenced project.  All project references should be true project references and not assembly references.  This is because we need all symbol information to be available when deriving JS symbol names.  When using dll references all non-public symbols will be missing.  Missing type: " + type.GetFullName());
                var reflectedType = Context.Instance.ReflectionCache.GetReflectedType(type);
                if (reflectedType != null && reflectedType.GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance).Any(x => x.Name == name))
{'fraction_non_alphanumeric': 0.09308421264869951, 'fraction_numerical': 0.0009409234491565293, 'mean_word_length': 1.6767404209390178, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6522557', 'n_tokens_mistral': 3500, 'n_tokens_neox': 3293, 'n_words': 1043}