<commit_before>using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Windows.Media;
using System.Xml.Linq;

namespace WpfMath
{
    // Parses definitions of predefined formulas from XML file.
    internal class TexPredefinedFormulaParser
    {
        public static readonly string resourceName = TexUtilities.ResourcesDataDirectory + "PredefinedTexFormulas.xml";

        private static IDictionary<string, Type> typeMappings;
        private static IDictionary<string, ArgumentValueParser> argValueParsers;
        private static IDictionary<string, ActionParser> actionParsers;
        private static TexFormulaParser formulaParser;

        static TexPredefinedFormulaParser()
        {
            typeMappings = new Dictionary<string, Type>();
            argValueParsers = new Dictionary<string, ArgumentValueParser>();
            actionParsers = new Dictionary<string, ActionParser>();
            formulaParser = new TexFormulaParser();
            var tempFormulas = new Dictionary<string, TexFormula>();

            typeMappings.Add("Formula", typeof(TexFormula));
            typeMappings.Add("string", typeof(string));
            typeMappings.Add("double", typeof(double));
            typeMappings.Add("int", typeof(int));
            typeMappings.Add("bool", typeof(bool));
            typeMappings.Add("char", typeof(char));
            typeMappings.Add("Color", typeof(Color));
            typeMappings.Add("Unit", typeof(TexUnit));
            typeMappings.Add("AtomType", typeof(TexAtomType));

            actionParsers.Add("CreateFormula", new CreateTeXFormulaParser(tempFormulas));
            actionParsers.Add("MethodInvocation", new MethodInvocationParser(tempFormulas));
            actionParsers.Add("Return", new ReturnParser(tempFormulas));

            argValueParsers.Add("Formula", new TeXFormulaValueParser(tempFormulas));
            argValueParsers.Add("string", new StringValueParser(tempFormulas));
            argValueParsers.Add("double", new DoubleValueParser(tempFormulas));
            argValueParsers.Add("int", new IntValueParser(tempFormulas));
            argValueParsers.Add("bool", new BooleanValueParser(tempFormulas));
            argValueParsers.Add("char", new CharValueParser(tempFormulas));
            argValueParsers.Add("Color", new ColorConstantValueParser(tempFormulas));
            argValueParsers.Add("Unit", new EnumParser(typeof(TexUnit), tempFormulas));
            argValueParsers.Add("AtomType", new EnumParser(typeof(TexAtomType), tempFormulas));
        }

        private static Type[] GetArgumentTypes(IEnumerable<XElement> args)
        {
            var result = new List<Type>();
            foreach (var curArg in args)
            {
                var typeName = curArg.AttributeValue("type");
                var type = typeMappings[typeName];
                Debug.Assert(type != null);
                result.Add(type);
            }

            return result.ToArray();
        }

        private static object[] GetArgumentValues(IDictionary<string, TexFormula> tempFormulas, IEnumerable<XElement> args)
        {
            var result = new List<object>();
            foreach (var curArg in args)
            {
                var typeName = curArg.AttributeValue("type");
                var value = curArg.AttributeValue("value");

                var parser = ((ArgumentValueParser)argValueParsers[typeName]);
                result.Add(parser.Parse(value, typeName));
            }

            return result.ToArray();
        }

        private XElement rootElement;

        public TexPredefinedFormulaParser()
        {
            var doc = XDocument.Load(new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)));
            this.rootElement = doc.Root;
        }

        public void Parse(IDictionary<string, Func<SourceSpan, TexFormula>> predefinedTeXFormulas)
        {
            var rootEnabled = rootElement.AttributeBooleanValue("enabled", true);
            if (rootEnabled)
            {
                foreach (var formulaElement in rootElement.Elements("Formula"))
                {
                    var enabled = formulaElement.AttributeBooleanValue("enabled", true);
                    if (enabled)
                    {
                        var formulaName = formulaElement.AttributeValue("name");
                        predefinedTeXFormulas.Add(formulaName, source => this.ParseFormula(source, formulaElement));
                    }
                }
            }
        }

        public TexFormula ParseFormula(SourceSpan source, XElement formulaElement)
        {
            foreach (var element in formulaElement.Elements())
            {
                var parser = actionParsers[element.Name.ToString()];
                if (parser == null)
                    continue;

                parser.Parse(source, element);
                if (parser is ReturnParser)
                    return ((ReturnParser)parser).Result;
            }
            return null;
        }

        public class MethodInvocationParser : ActionParser
        {
            public MethodInvocationParser(IDictionary<string, TexFormula> tempFormulas)
                : base(tempFormulas)
            {
            }

            public override void Parse(SourceSpan source, XElement element)
            {
                var methodName = element.AttributeValue("name");
                var objectName = element.AttributeValue("formula");
                var args = element.Elements("Argument");

                var formula = this.TempFormulas[objectName];
                Debug.Assert(formula != null);

                var argTypes = GetArgumentTypes(args);
                var argValues = GetArgumentValues(this.TempFormulas, args);

                var helper = new TexFormulaHelper(formula, source);
                typeof(TexFormulaHelper).GetMethod(methodName, argTypes).Invoke(helper, argValues);
            }
        }

        public class CreateTeXFormulaParser : ActionParser
        {
            public CreateTeXFormulaParser(IDictionary<string, TexFormula> tempFormulas)
                : base(tempFormulas)
            {
            }

            public override void Parse(SourceSpan source, XElement element)
            {
                var name = element.AttributeValue("name");
                var args = element.Elements("Argument");

                var argTypes = GetArgumentTypes(args);
                var argValues = GetArgumentValues(this.TempFormulas, args);

                Debug.Assert(argValues.Length == 1 || argValues.Length == 0);
                TexFormula formula = null;
                if (argValues.Length == 1)
                {
                    var parser = new TexFormulaParser();
                    formula = parser.Parse((string)argValues[0]);
                }
                else<commit_msg>Delete redundant parameter<commit_after>using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Windows.Media;
using System.Xml.Linq;

namespace WpfMath
{
    // Parses definitions of predefined formulas from XML file.
    internal class TexPredefinedFormulaParser
    {
        public static readonly string resourceName = TexUtilities.ResourcesDataDirectory + "PredefinedTexFormulas.xml";

        private static IDictionary<string, Type> typeMappings;
        private static IDictionary<string, ArgumentValueParser> argValueParsers;
        private static IDictionary<string, ActionParser> actionParsers;
        private static TexFormulaParser formulaParser;

        static TexPredefinedFormulaParser()
        {
            typeMappings = new Dictionary<string, Type>();
            argValueParsers = new Dictionary<string, ArgumentValueParser>();
            actionParsers = new Dictionary<string, ActionParser>();
            formulaParser = new TexFormulaParser();
            var tempFormulas = new Dictionary<string, TexFormula>();

            typeMappings.Add("Formula", typeof(TexFormula));
            typeMappings.Add("string", typeof(string));
            typeMappings.Add("double", typeof(double));
            typeMappings.Add("int", typeof(int));
            typeMappings.Add("bool", typeof(bool));
            typeMappings.Add("char", typeof(char));
            typeMappings.Add("Color", typeof(Color));
            typeMappings.Add("Unit", typeof(TexUnit));
            typeMappings.Add("AtomType", typeof(TexAtomType));

            actionParsers.Add("CreateFormula", new CreateTeXFormulaParser(tempFormulas));
            actionParsers.Add("MethodInvocation", new MethodInvocationParser(tempFormulas));
            actionParsers.Add("Return", new ReturnParser(tempFormulas));

            argValueParsers.Add("Formula", new TeXFormulaValueParser(tempFormulas));
            argValueParsers.Add("string", new StringValueParser(tempFormulas));
            argValueParsers.Add("double", new DoubleValueParser(tempFormulas));
            argValueParsers.Add("int", new IntValueParser(tempFormulas));
            argValueParsers.Add("bool", new BooleanValueParser(tempFormulas));
            argValueParsers.Add("char", new CharValueParser(tempFormulas));
            argValueParsers.Add("Color", new ColorConstantValueParser(tempFormulas));
            argValueParsers.Add("Unit", new EnumParser(typeof(TexUnit), tempFormulas));
            argValueParsers.Add("AtomType", new EnumParser(typeof(TexAtomType), tempFormulas));
        }

        private static Type[] GetArgumentTypes(IEnumerable<XElement> args)
        {
            var result = new List<Type>();
            foreach (var curArg in args)
            {
                var typeName = curArg.AttributeValue("type");
                var type = typeMappings[typeName];
                Debug.Assert(type != null);
                result.Add(type);
            }

            return result.ToArray();
        }

        private static object[] GetArgumentValues(IEnumerable<XElement> args)
        {
            var result = new List<object>();
            foreach (var curArg in args)
            {
                var typeName = curArg.AttributeValue("type");
                var value = curArg.AttributeValue("value");

                var parser = ((ArgumentValueParser)argValueParsers[typeName]);
                result.Add(parser.Parse(value, typeName));
            }

            return result.ToArray();
        }

        private XElement rootElement;

        public TexPredefinedFormulaParser()
        {
            var doc = XDocument.Load(new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)));
            this.rootElement = doc.Root;
        }

        public void Parse(IDictionary<string, Func<SourceSpan, TexFormula>> predefinedTeXFormulas)
        {
            var rootEnabled = rootElement.AttributeBooleanValue("enabled", true);
            if (rootEnabled)
            {
                foreach (var formulaElement in rootElement.Elements("Formula"))
                {
                    var enabled = formulaElement.AttributeBooleanValue("enabled", true);
                    if (enabled)
                    {
                        var formulaName = formulaElement.AttributeValue("name");
                        predefinedTeXFormulas.Add(formulaName, source => this.ParseFormula(source, formulaElement));
                    }
                }
            }
        }

        public TexFormula ParseFormula(SourceSpan source, XElement formulaElement)
        {
            foreach (var element in formulaElement.Elements())
            {
                var parser = actionParsers[element.Name.ToString()];
                if (parser == null)
                    continue;

                parser.Parse(source, element);
                if (parser is ReturnParser)
                    return ((ReturnParser)parser).Result;
            }
            return null;
        }

        public class MethodInvocationParser : ActionParser
        {
            public MethodInvocationParser(IDictionary<string, TexFormula> tempFormulas)
                : base(tempFormulas)
            {
            }

            public override void Parse(SourceSpan source, XElement element)
            {
                var methodName = element.AttributeValue("name");
                var objectName = element.AttributeValue("formula");
                var args = element.Elements("Argument");

                var formula = this.TempFormulas[objectName];
                Debug.Assert(formula != null);

                var argTypes = GetArgumentTypes(args);
                var argValues = GetArgumentValues(args);

                var helper = new TexFormulaHelper(formula, source);
                typeof(TexFormulaHelper).GetMethod(methodName, argTypes).Invoke(helper, argValues);
            }
        }

        public class CreateTeXFormulaParser : ActionParser
        {
            public CreateTeXFormulaParser(IDictionary<string, TexFormula> tempFormulas)
                : base(tempFormulas)
            {
            }

            public override void Parse(SourceSpan source, XElement element)
            {
                var name = element.AttributeValue("name");
                var args = element.Elements("Argument");

                var argTypes = GetArgumentTypes(args);
                var argValues = GetArgumentValues(args);

                Debug.Assert(argValues.Length == 1 || argValues.Length == 0);
                TexFormula formula = null;
                if (argValues.Length == 1)
                {
                    var parser = new TexFormulaParser();
                    formula = parser.Parse((string)argValues[0]);
                }
                else
{'fraction_non_alphanumeric': 0.09246894967334339, 'fraction_numerical': 0.000574341302318903, 'mean_word_length': 2.1038324420677363, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 36, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, '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': '6333159', 'n_tokens_mistral': 3386, 'n_tokens_neox': 3221, 'n_words': 692}