public void Compiler_Analyze_SimpleModule()
        {
            using (var tester = new CompilerTester(nameof(Compiler_Analyze_SimpleModule), Source))
            {
                var compiler = tester.Compiler;
                var context = compiler.Context;
                var compileUnit = context.CompileUnits.First();
                var sourceFile = compileUnit.SourceFiles.First();
                var parseUnit = new ParseUnit { SourceFile = sourceFile };

                var parse = new Task(new ParseSourceFile(context, parseUnit).GetStepAction(context.CancelSource.Token));
                parse.Start();
                parse.Wait();
                Assert.AreEqual(0, compileUnit.Errors.Count(), "parse errors: " + string.Join("; ", compileUnit.Errors.Select(e => e.Message)));

                var analyzeUnit = new AnalysisUnit { ParseUnits = new List<ParseUnit>() { parseUnit } };
                var analyze = new Task(new AnalyzeSourceFile(context, analyzeUnit, parseUnit).GetStepAction(context.CancelSource.Token));
                analyze.Start();
                analyze.Wait();

                Assert.AreEqual(0, compileUnit.Errors.Count(), "analyze errors: " + string.Join("; ", compileUnit.Errors.Select(e => e.Message)));

                var module = analyzeUnit.Modules.Values.Single(m => m.Name.Name == "One");
                var binding = module.Bindings.Values.Single(b => b.Name.Name == "f");
                Assert.IsFalse(binding.IsPublic);

                Assert.IsInstanceOfType(binding.Expression, typeof(Analyze.Expressions.IntegerLiteral));
                var intLiteral = binding.Expression as Analyze.Expressions.IntegerLiteral;

                Assert.IsInstanceOfType(intLiteral.ResolvedType, typeof(Analyze.Builtins.SystemInt32));
                var val = (int)intLiteral.IntValue;
                Assert.AreEqual(123, val);
            }
        }
예제 #2
0
        ParseUnit ProcessTemplates(ParseUnit inputUnit)
        {
            var templatesFiltered = LoadTemplates(inputUnit);
            var templatesExpanded = ExpandTemplates(templatesFiltered);

            return(templatesExpanded);
        }
        public void Compiler_Parse_SimpleModule()
        {
            using (var tester = new CompilerTester(nameof(Compiler_Parse_SimpleModule), Source))
            {
                var compiler    = tester.Compiler;
                var context     = compiler.Context;
                var compileUnit = context.CompileUnits.First();
                var sourceFile  = compileUnit.SourceFiles.First();
                var parseUnit   = new ParseUnit {
                    SourceFile = sourceFile
                };

                var parse = new Task(new ParseSourceFile(context, parseUnit).GetStepAction(context.CancelSource.Token));
                parse.Start();
                parse.Wait();
                Assert.AreEqual(0, compileUnit.Errors.Count(), "parse errors: " + string.Join("; ", compileUnit.Errors.Select(e => e.Message)));

                var modules = sourceFile.ParseTree.Children.OfType <Parse.Syntax.Module>().ToList();
                Assert.AreEqual(1, modules.Count);
                Assert.AreEqual("One", modules.First().Name.Text);

                var bindings = modules.First().Body.OfType <Parse.Syntax.Binding>().ToList();
                Assert.AreEqual(1, bindings.Count);
                Assert.AreEqual("f", bindings.First().Name.Text);

                var literals = bindings.First().Body.OfType <Parse.Syntax.Literal <BigInteger> >().ToList();
                Assert.AreEqual(1, literals.Count);

                var oneTwoThree = new BigInteger(123);
                Assert.AreEqual(oneTwoThree, literals.First().Value);
            }
        }
예제 #4
0
        ParseUnit LoadTemplates(ParseUnit inputUnit)
        {
            ParseUnit result = new ParseUnit(path: inputUnit.FullPath, version: inputUnit.Version);

            result.Elements = inputUnit.Elements;
            var templates = inputUnit.Elements.Where(_ => _.Name == ConfigurationConstants.Tags.TEMPLATE);

            if (!templates.All(_ => _.Attribute(ConfigurationConstants.Attrs.ID) != null))
            {
                Log.WriteLine(LogLevel.Error, "All <" + ConfigurationConstants.Tags.TEMPLATE + "> tags must have '" + ConfigurationConstants.Attrs.ID + "' set.");
                throw new FormatException("All <" + ConfigurationConstants.Tags.TEMPLATE + "> tags must have '" + ConfigurationConstants.Attrs.ID + "' set.");
            }
            var mergedTemplates = from t in templates
                                  group t.Elements() by t.Attribute(ConfigurationConstants.Attrs.ID).Value into g
                                  select CreatePair(g.Key, MergeSections(g));

            foreach (var template in mergedTemplates)
            {
                if (m_loadedTemplates.ContainsKey(template.Key))
                {
                    m_loadedTemplates[template.Key] = template.Value.ToList();
                }
                else
                {
                    m_loadedTemplates.Add(template.Key, template.Value.ToList());
                }
            }
            return(result);
        }
예제 #5
0
        ParseUnit Pipeline(ParseUnit elements)
        {
            var importProcessed   = ProcessImports(elements);
            var templateProcessed = ProcessTemplates(importProcessed);
            var mergeProcessed    = ProcessMerge(templateProcessed);

            return(mergeProcessed);
        }
예제 #6
0
 public ParserState()
 {
     Position        = new Vector3();
     Plane           = ArcPlane.XY;
     DistanceMode    = ParseDistanceMode.Absolute;
     ArcDistanceMode = ParseDistanceMode.Relative;
     Unit            = ParseUnit.Metric;
     LastMotionMode  = -1;
 }
예제 #7
0
 public ParserState()
 {
     Position        = new Vector3();
     Plane           = ArcPlane.XY;
     Feed            = 100;
     DistanceMode    = ParseDistanceMode.Absolute;
     ArcDistanceMode = ParseDistanceMode.Incremental;
     Unit            = ParseUnit.Metric;
     LastMotionMode  = -1;
 }
예제 #8
0
		public ParserState()
		{
			Position = new Vector3();
			Plane = ArcPlane.XY;
			Feed = 100;
			DistanceMode = ParseDistanceMode.Absolute;
			ArcDistanceMode = ParseDistanceMode.Incremental;
			Unit = ParseUnit.Metric;
			LastMotionMode = -1;
		}
예제 #9
0
        internal static TQuantity Parse <TQuantity, TUnitType>([NotNull] string str,
                                                               [CanBeNull] IFormatProvider formatProvider,
                                                               [NotNull] ParseUnit <TQuantity> parseUnit,
                                                               [NotNull] Func <TQuantity, TQuantity, TQuantity> add)
        {
            if (str == null)
            {
                throw new ArgumentNullException(nameof(str));
            }
            if (parseUnit == null)
            {
                throw new ArgumentNullException(nameof(parseUnit));
            }
            if (add == null)
            {
                throw new ArgumentNullException(nameof(add));
            }

            NumberFormatInfo numFormat = formatProvider != null
                ? (NumberFormatInfo)formatProvider.GetFormat(typeof(NumberFormatInfo))
                : NumberFormatInfo.CurrentInfo;

            string numRegex = string.Format(@"[\d., {0}{1}]*\d",
                                                                               // allows digits, dots, commas, and spaces in the quantity (must end in digit)
                                            numFormat.NumberGroupSeparator,    // adds provided (or current) culture's group separator
                                            numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator

            const string exponentialRegex = @"(?:[eE][-+]?\d+)?)";

            string[] unitAbbreviations = UnitSystem.GetCached(formatProvider)
                                         .GetAllAbbreviations(typeof(TUnitType))
                                         .OrderByDescending(s => s.Length) // Important to order by length -- if "m" is before "mm" and the input is "mm", it will match just "m" and throw invalid string error
                                         .Select(Regex.Escape)             // Escape special regex characters
                                         .ToArray();

            string unitsRegex = $"({String.Join("|", unitAbbreviations)})";

            string regexString = string.Format(@"(?:\s*(?<value>[-+]?{0}{1}{2}{3})?{4}{5}",
                                               numRegex,                  // capture base (integral) Quantity value
                                               exponentialRegex,          // capture exponential (if any), end of Quantity capturing
                                               @"\s?",                    // ignore whitespace (allows both "1kg", "1 kg")
                                               $@"(?<unit>{unitsRegex})", // capture Unit by list of abbreviations
                                               @"(and)?,?",               // allow "and" & "," separators between quantities
                                               @"(?<invalid>[a-z]*)?");   // capture invalid input

            List <TQuantity> quantities = ParseWithRegex(regexString, str, parseUnit, formatProvider);

            if (quantities.Count == 0)
            {
                throw new ArgumentException(
                          "Expected string to have at least one pair of quantity and unit in the format"
                          + " \"&lt;quantity&gt; &lt;unit&gt;\". Eg. \"5.5 m\" or \"1ft 2in\"");
            }
            return(quantities.Aggregate(add));
        }
예제 #10
0
 public ParserState()
 {
     Position        = Vector3.MinValue;
     PositionValid   = new bool[] { false, false, false };
     Plane           = ArcPlane.XY;
     Feed            = 0;
     DistanceMode    = ParseDistanceMode.Absolute;
     ArcDistanceMode = ParseDistanceMode.Incremental;
     Unit            = ParseUnit.Metric;
     LastMotionMode  = -1;
 }
예제 #11
0
        private XmlConfiguration(string filename)
        {
            RootConfigFullPath = GetFullPath(filename);
            var loaded = LoadFile(filename);

            //filename shoule be added in case filename has the same directory with a directory in a import entry
            m_importedFiles.Add(RootConfigFullPath);

            RootConfigVersion = loaded.Version;
            m_finalUnit       = Pipeline(loaded);
        }
예제 #12
0
        /// <summary>
        /// Merge the multiple local configuration sections and multiple cluster configuration sections
        /// </summary>
        /// <param name="inputUnit"></param>
        /// <returns></returns>
        private ParseUnit ProcessMerge(ParseUnit inputUnit)
        {
            // pick local sections and config entries specified directly in root
            var localSections = inputUnit.Elements.Where(_ => _.Name != ConfigurationConstants.Tags.CLUSTER);

            // merge local
            var mergedEntries = MergeSections(localSections.Select(_ => _.Name == ConfigurationConstants.Tags.LOCAL ? _.Elements() : new[] { _ }));

            XElement localSection = new XElement(ConfigurationConstants.Tags.LOCAL, mergedEntries);

            var clusterSections = inputUnit.Elements
                                  .Where(_ => _.Name == ConfigurationConstants.Tags.CLUSTER)
                                  .GroupBy(_ => _.Attribute(ConfigurationConstants.Attrs.ID)?.Value)
                                  .Select(_ =>
            {
                foreach (var cluster in _)
                {
                    foreach (var node in cluster.Elements())
                    {
                        var entries = MergeSections(new[] { node.Elements() });
                        node.RemoveNodes();
                        foreach (var entry in entries)
                        {
                            node.Add(entry);
                        }
                    }
                    var defaultNodes = cluster.Elements().Where(__ => __.Name == ConfigurationConstants.Tags.DEFAULT);
                    Dictionary <string, XElement> defaultEntries = new Dictionary <string, XElement>();

                    foreach (var node in defaultNodes)
                    {
                        foreach (var entry in node.Elements())
                        {
                            defaultEntries[entry.Name.LocalName] = entry;
                        }
                    }

                    foreach (var node in cluster.Elements())
                    {
                        foreach (var entry in defaultEntries)
                        {
                            if (node.Element(entry.Key) == null)
                            {
                                node.Add(entry.Value);
                            }
                        }
                    }
                }
                return(_);
            }).Select(_ => MergeSections(new [] { _ }).First());

            return(new ParseUnit(new[] { localSection }.Concat(clusterSections)));
        }
예제 #13
0
        internal static TUnit ParseUnit <TUnit>([NotNull] string str,
                                                [CanBeNull] IFormatProvider formatProvider,
                                                [NotNull] ParseUnit <TUnit> parseUnit,
                                                [NotNull] Func <TUnit, TUnit, TUnit> add)
        {
            if (str == null)
            {
                throw new ArgumentNullException(nameof(str));
            }
            if (parseUnit == null)
            {
                throw new ArgumentNullException(nameof(parseUnit));
            }
            if (add == null)
            {
                throw new ArgumentNullException(nameof(add));
            }

            var numFormat = formatProvider != null
                ? (NumberFormatInfo)formatProvider.GetFormat(typeof(NumberFormatInfo))
                : NumberFormatInfo.CurrentInfo;

            string numRegex = string.Format(@"[\d., {0}{1}]*\d",
                                                                               // allows digits, dots, commas, and spaces in the quantity (must end in digit)
                                            numFormat.NumberGroupSeparator,    // adds provided (or current) culture's group separator
                                            numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator

            const string exponentialRegex = @"(?:[eE][-+]?\d+)?)";

            string regexString = string.Format(@"(?:\s*(?<value>[-+]?{0}{1}{2}{3})?{4}{5}",
                                               numRegex,                // capture base (integral) Quantity value
                                               exponentialRegex,        // capture exponential (if any), end of Quantity capturing
                                               @"\s?",                  // ignore whitespace (allows both "1kg", "1 kg")
                                               @"(?<unit>[^\s\d,]+)",   // capture Unit (non-whitespace) input
                                               @"(and)?,?",             // allow "and" & "," separators between quantities
                                               @"(?<invalid>[a-z]*)?"); // capture invalid input

            List <TUnit> quantities = ParseWithRegex(regexString, str, parseUnit, formatProvider);

            if (quantities.Count == 0)
            {
                throw new ArgumentException(
                          "Expected string to have at least one pair of quantity and unit in the format"
                          + " \"&lt;quantity&gt; &lt;unit&gt;\". Eg. \"5.5 m\" or \"1ft 2in\"");
            }
            return(quantities.Aggregate(add));
        }
예제 #14
0
        ParseUnit ProcessImports(ParseUnit parentUnit)
        {
            ParseUnit result = new ParseUnit();

            foreach (var e in parentUnit.Elements)
            {
                if (e.Name == ConfigurationConstants.Tags.IMPORT)
                {
                    result.Elements.AddRange(ProcessImportNode(e, parentUnit).Elements);
                }
                else
                {
                    result.Elements.Add(e);
                }
            }
            return(result);
        }
예제 #15
0
        public string Format(String inputSql, BackgroundWorker bw)
        {
            bw.ReportProgress(0);

            var pr = Parser.Parse(inputSql.Trim());
            string outSql = "";

            bw.ReportProgress(10);

            LinkedList<Token> tokenList = new LinkedList<Token>();

            // build a full list
            foreach (Token t in pr.Tokens)
            {
                tokenList.AddLast(t);
            }

            bw.ReportProgress(20);

            ParseUnit pu = new ParseUnit();
            pu.indentDepth = 0;
            pu.clauseStack = new Stack<Token>();
            pu.sqlBits = new LinkedList<string>();
            pu.token = tokenList.First;

            int totalTokens = tokenList.Count;
            int currentTokenCount = 0;

            while(pu.token != null) {
                Interpreter interp = InterpreterFactory.Get(pu.token.Value);
                pu.sqlBits.AddLast(interp.Interpret(ref pu));
                pu.token = pu.token.Next;

                currentTokenCount += 1; bw.ReportProgress((currentTokenCount * 80 /totalTokens) + 20);
            }

            foreach (String sqlString in pu.sqlBits) {
                outSql += sqlString;
            }

            outSql = Regex.Replace(outSql, @"^(\s*)$", "", RegexOptions.Multiline);
            return outSql.Trim();
        }
예제 #16
0
        public void Compiler_Analyze_SimpleModule()
        {
            using (var tester = new CompilerTester(nameof(Compiler_Analyze_SimpleModule), Source))
            {
                var compiler    = tester.Compiler;
                var context     = compiler.Context;
                var compileUnit = context.CompileUnits.First();
                var sourceFile  = compileUnit.SourceFiles.First();
                var parseUnit   = new ParseUnit {
                    SourceFile = sourceFile
                };

                var parse = new Task(new ParseSourceFile(context, parseUnit).GetStepAction(context.CancelSource.Token));
                parse.Start();
                parse.Wait();
                Assert.AreEqual(0, compileUnit.Errors.Count(), "parse errors: " + string.Join("; ", compileUnit.Errors.Select(e => e.Message)));

                var analyzeUnit = new AnalysisUnit {
                    ParseUnits = new List <ParseUnit>()
                    {
                        parseUnit
                    }
                };
                var analyze = new Task(new AnalyzeSourceFile(context, analyzeUnit, parseUnit).GetStepAction(context.CancelSource.Token));
                analyze.Start();
                analyze.Wait();

                Assert.AreEqual(0, compileUnit.Errors.Count(), "analyze errors: " + string.Join("; ", compileUnit.Errors.Select(e => e.Message)));

                var module  = analyzeUnit.Modules.Values.Single(m => m.Name.Name == "One");
                var binding = module.Bindings.Values.Single(b => b.Name.Name == "f");
                Assert.IsFalse(binding.IsPublic);

                Assert.IsInstanceOfType(binding.Expression, typeof(Analyze.Expressions.IntegerLiteral));
                var intLiteral = binding.Expression as Analyze.Expressions.IntegerLiteral;

                Assert.IsInstanceOfType(intLiteral.ResolvedType, typeof(Analyze.Builtins.SystemInt32));
                var val = (int)intLiteral.IntValue;
                Assert.AreEqual(123, val);
            }
        }
예제 #17
0
        ParseUnit ImportFile(string filename, ParseUnit parentUnit)
        {
            var fullpath = GetFullPath(filename);

            if (m_importedFiles.Contains(fullpath))
            {
                Log.WriteLine(LogLevel.Warning, "Ignoring file '" + fullpath + "' because it is already imported.");
                return(new ParseUnit());
            }

            var loaded = LoadFile(filename);

            if (loaded.Version != RootConfigVersion)
            {
                Log.WriteLine(LogLevel.Warning, "Ignoring file '" + filename + "' because of confliting config version:");
                Log.WriteLine(LogLevel.Warning, "Expected:" + RootConfigVersion + ", Found:" + loaded.Version + "");
                return(new ParseUnit());
            }
            Log.WriteLine(LogLevel.Info, "TrinityConfig:" + fullpath + " imported.");
            m_importedFiles.Add(fullpath);
            return(loaded);
        }
예제 #18
0
        ParseUnit ProcessImportNode(XElement importNode, ParseUnit parentUnit)
        {
            var fileAttr = importNode.Attribute(ConfigurationConstants.Attrs.FILE);
            var dirAttr  = importNode.Attribute(ConfigurationConstants.Attrs.DIRECTORY);

            if (fileAttr != null)
            {
                var path = fileAttr.Value;
                if (!File.Exists(path))
                {
                    Log.WriteLine(LogLevel.Info, "Path " + path + " does not exist or is not a file.");
                    throw new FileNotFoundException("Path " + path + " does not exist or is not a file.");
                }
                var loadedImportFile = ImportFile(path, parentUnit);
                return(Pipeline(loadedImportFile));
            }

            if (dirAttr != null)
            {
                var path = dirAttr.Value;
                if (!Directory.Exists(path))
                {
                    Log.WriteLine(LogLevel.Info, "Directory " + path + " does not exist or is not a directory.");
                    throw new DirectoryNotFoundException("Directory " + path + " does not exist or is not a directory.");
                }
                var result      = new ParseUnit();
                var sortedFiles = Directory.GetFiles(path).OrderBy(f => f);
                foreach (var filename in sortedFiles)
                {
                    if (filename.ToLower().EndsWith(".xml"))
                    {
                        var loadedImportFile = ImportFile(filename, parentUnit);
                        result.Elements.AddRange(Pipeline(loadedImportFile).Elements);
                    }
                }
                return(result);
            }
            return(parentUnit);
        }
예제 #19
0
        ParseUnit ExpandTemplates(ParseUnit inputUnit)
        {
            var result = new ParseUnit(path: inputUnit.FullPath, version: inputUnit.Version);

            result.Elements = inputUnit.Elements.Select(section =>
            {
                if (section.Name == ConfigurationConstants.Tags.LOCAL)
                {
                    return(ExpandTemplateForANode(section));
                }
                if (section.Name == ConfigurationConstants.Tags.CLUSTER)
                {
                    var defaultElements   = section.Elements().Where(_ => _.Name == ConfigurationConstants.Tags.DEFAULT);
                    var defaultAsTemplate = new List <IEnumerable <XElement> >();
                    if (defaultElements.Count() != 0)
                    {
                        defaultAsTemplate.Add(MergeSections(new List <IEnumerable <XElement> > {
                            defaultElements
                        }).First().Elements());
                    }
                    var newChildren = section.Elements().Select(e =>
                    {
                        if (e.Name == ConfigurationConstants.Tags.SERVER || e.Name == ConfigurationConstants.Tags.PROXY)
                        {
                            return(ExpandTemplateForANode(e, defaultAsTemplate));
                        }
                        return(e);
                    });
                    var newElem = new XElement(section.Name, section.Attributes());
                    newElem.Add(newChildren);
                    return(newElem);
                }
                return(section);
            }).ToList();
            return(result);
        }
예제 #20
0
        public void Compiler_Parse_SimpleModule()
        {
            using (var tester = new CompilerTester(nameof(Compiler_Parse_SimpleModule), Source))
            {
                var compiler = tester.Compiler;
                var context = compiler.Context;
                var compileUnit = context.CompileUnits.First();
                var sourceFile = compileUnit.SourceFiles.First();
                var parseUnit = new ParseUnit { SourceFile = sourceFile };

                var parse = new Task(new ParseSourceFile(context, parseUnit).GetStepAction(context.CancelSource.Token));
                parse.Start();
                parse.Wait();
                Assert.AreEqual(0, compileUnit.Errors.Count(), "parse errors: " + string.Join("; ", compileUnit.Errors.Select(e => e.Message)));

                var modules = sourceFile.ParseTree.Children.OfType<Parse.Syntax.Module>().ToList();
                Assert.AreEqual(1, modules.Count);
                Assert.AreEqual("One", modules.First().Name.Text);

                var bindings = modules.First().Body.OfType<Parse.Syntax.Binding>().ToList();
                Assert.AreEqual(1, bindings.Count);
                Assert.AreEqual("f", bindings.First().Name.Text);

                var literals = bindings.First().Body.OfType<Parse.Syntax.Literal<BigInteger>>().ToList();
                Assert.AreEqual(1, literals.Count);

                var oneTwoThree = new BigInteger(123);
                Assert.AreEqual(oneTwoThree, literals.First().Value);
            }
        }
예제 #21
0
        /// <summary>
        ///     Parse a string given a particular regular expression.
        /// </summary>
        /// <exception cref="UnitsNetException">Error parsing string.</exception>
        private static List <TQuantity> ParseWithRegex <TQuantity>(string regexString, string str, ParseUnit <TQuantity> parseUnit,
                                                                   IFormatProvider formatProvider = null)
        {
            var             regex     = new Regex(regexString);
            MatchCollection matches   = regex.Matches(str.Trim());
            var             converted = new List <TQuantity>();

            foreach (Match match in matches)
            {
                GroupCollection groups = match.Groups;

                string valueString = groups["value"].Value;
                string unitString  = groups["unit"].Value;
                if (groups["invalid"].Value != "")
                {
                    var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
                    newEx.Data["input"]          = str;
                    newEx.Data["matched value"]  = valueString;
                    newEx.Data["matched unit"]   = unitString;
                    newEx.Data["formatprovider"] = formatProvider?.ToString();
                    throw newEx;
                }
                if ((valueString == "") && (unitString == ""))
                {
                    continue;
                }

                try
                {
                    converted.Add(parseUnit(valueString, unitString, formatProvider));
                }
                catch (AmbiguousUnitParseException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    var newEx = new UnitsNetException("Error parsing string.", ex);
                    newEx.Data["input"]          = str;
                    newEx.Data["matched value"]  = valueString;
                    newEx.Data["matched unit"]   = unitString;
                    newEx.Data["formatprovider"] = formatProvider?.ToString();
                    throw newEx;
                }
            }
            return(converted);
        }
예제 #22
0
        private ParseUnit ProcessMerge(ParseUnit inputUnit)
        {
            ParseUnit mergedSections = new ParseUnit();


            // merge local
            var localSections = inputUnit.Elements
                                .Where(_ => _.Name == ConfigurationConstants.Tags.LOCAL);
            var      mergedEntries = MergeSections(new List <IEnumerable <XElement> >(localSections.Select(_ => _.Elements())));
            XElement localSection  = new XElement(ConfigurationConstants.Tags.LOCAL);

            foreach (var entry in mergedEntries)
            {
                localSection.Add(entry);
            }
            mergedSections.Elements.Add(localSection);

            var clusterSections = inputUnit.Elements
                                  .Where(_ => _.Name == ConfigurationConstants.Tags.CLUSTER)
                                  .GroupBy(_ =>
            {
                var attr = _.Attribute(ConfigurationConstants.Attrs.ID);
                if (attr != null)
                {
                    return(attr.Value);
                }
                else
                {
                    return(null);
                }
            })
                                  .Select(_ =>
            {
                foreach (var cluster in _)
                {
                    foreach (var node in cluster.Elements())
                    {
                        var entries = MergeSections(new List <IEnumerable <XElement> > {
                            node.Elements()
                        });
                        node.RemoveNodes();
                        foreach (var entry in entries)
                        {
                            node.Add(entry);
                        }
                    }
                    var defaultNodes = cluster.Elements().Where(__ => __.Name == ConfigurationConstants.Tags.DEFAULT);
                    Dictionary <string, XElement> defaultEntries = new Dictionary <string, XElement>();

                    foreach (var node in defaultNodes)
                    {
                        foreach (var entry in node.Elements())
                        {
                            defaultEntries[entry.Name.LocalName] = entry;
                        }
                    }

                    foreach (var node in cluster.Elements())
                    {
                        foreach (var entry in defaultEntries)
                        {
                            if (node.Element(entry.Key) == null)
                            {
                                node.Add(entry.Value);
                            }
                        }
                    }
                }
                return(_);
            }).Select(_ =>
            {
                return(MergeSections(new List <IEnumerable <XElement> > {
                    _
                }).First());
            });

            mergedSections.Elements.AddRange(clusterSections);

            return(mergedSections);
        }
예제 #23
0
 public AnalyzeSourceFile(CompilerContext context, AnalysisUnit analysisUnit, ParseUnit parseUnit)
     : base(context, analysisUnit)
 {
     ParseUnit = parseUnit;
 }