Пример #1
0
        public void ReloadConfigs()
        {
            Update(x =>
            {
                const string detailsPrefix  = "Details.";
                const string groupingPrefix = "Grouping.";
                var lexer           = new IniLexer();
                string sectionName  = null;
                string propertyName = null;

                x.SectionDetails.Clear();

                lexer.Parse(x.Project.Contents, (token, position, type) =>
                {
                    if (type == IniLexer.StyleSection)
                    {
                        sectionName = token.Trim('[', ']');
                    }
                    else if (type == IniLexer.StyleKey)
                    {
                        propertyName = token.Trim();
                    }
                    else if (type == IniLexer.StyleValue)
                    {
                        token = token.Trim();
                        // read section style
                        if (sectionName.StartsWith(detailsPrefix, StringComparison.OrdinalIgnoreCase))
                        {
                            var blockName = sectionName.Substring(detailsPrefix.Length);
                            if (!x.SectionDetails.TryGetValue(blockName, out SectionStyle s))
                            {
                                x.SectionDetails[blockName] = s = new SectionStyle();
                            }

                            if (propertyName.IgnoreCaseEqual("backColor"))
                            {
                                s.BackColor = token.ToColor();
                            }
                            else if (propertyName.IgnoreCaseEqual("foreColor"))
                            {
                                s.ForeColor = token.ToColor();
                            }
                            else if (propertyName.IgnoreCaseEqual("borderColor"))
                            {
                                s.BorderColor = token.ToColor();
                            }
                        }
                        // read section grouping
                        else if (sectionName.StartsWith(groupingPrefix, StringComparison.OrdinalIgnoreCase))
                        {
                            var blockName = sectionName.Substring(groupingPrefix.Length);
                            if (!x.SectionGroups.TryGetValue(blockName, out SectionGroup s))
                            {
                                x.SectionGroups[blockName] = s = new SectionGroup();
                            }
                            // process
                            var parts = token.Split('*');
                            if (parts.Length > 2)
                            {
                                LogError($"Invalid grouping match pattern: {token}. Valid pattern must contains only ONE wildcard");
                                return;
                            }
                            s.Patterns.Add(new Regex("^" + string.Join(".+?", parts.Select(Regex.Escape)) + "$", RegexOptions.Compiled | RegexOptions.IgnoreCase));
                        }
                    }
                });
            });
        }
Пример #2
0
        private async Task <AData> InternalAnalyze(Task <AData> oldData)
        {
            var stopwatch = new Stopwatch();

            stopwatch.Start();
            // should parse definition and template files first
            var filePaths = GetProjectDocuments(Model.Project?.FullPath)
                            .Concat(GetOpenedDocumentPaths())
                            .ToArray();

            if (filePaths.Length == 0)
            {
                return(await oldData);
            }

            var lexer     = new IniLexer();
            var analytics = new AData();

            foreach (var filePath in filePaths)
            {
                var fileId   = FileId(filePath);
                var file     = analytics.Files[fileId] = new AData.FileDef(filePath);
                var contents = ReadFile(filePath);

                // add to generic defs by default
                if (file.Type == AData.FileType.Definition)
                {
                    analytics.Definitions[string.Empty].Add(file);
                }

                string         propertyName = null;
                string         sectionName  = null;
                AData.Location lastLocation = null;
                lexer.Parse(contents, (token, position, type) =>
                {
                    switch (type)
                    {
                    case IniLexer.StyleSection:
                        if (lastLocation != null)
                        {
                            // extend last section location
                            lastLocation.EndPosition = position - 1;
                        }
                        sectionName                 = token.Substring(1, token.Length - 2).Trim();
                        lastLocation                = analytics.AddRef("s:" + sectionName, fileId, position);
                        lastLocation.TextLength     = token.Length;
                        file.Locations[sectionName] = lastLocation;
                        analytics.AddDef(file, sectionName);
                        break;

                    case IniLexer.StyleKey:
                        propertyName = token.Trim();
                        break;

                    case IniLexer.StyleValue:
                        if (string.IsNullOrWhiteSpace(sectionName))
                        {
                            Debug.WriteLine("Invalid data. {0}: {1}", filePath, position);
                        }
                        else
                        {
                            var trimmedValue = token.Trim();
                            analytics.AddDef(file, sectionName, propertyName, trimmedValue);
                        }
                        break;
                    }
                }, exploreValues: false);

                // there is single section
                if (lastLocation != null && lastLocation.EndPosition == -1)
                {
                    lastLocation.EndPosition = contents.Length;
                }
            }


            // process generic properties
            foreach (var definitions in analytics.Definitions.Values)
            {
                foreach (var file in definitions)
                {
                    if (file.Sections.TryGetValue(string.Empty, out AData.SectionDef genericSection))
                    {
                        var shouldMoveProperties = genericSection.Properties.Where(x => !string.IsNullOrWhiteSpace(x.Value.ApplyTo)).ToArray();

                        foreach (var pair in shouldMoveProperties)
                        {
                            genericSection.Properties.Remove(pair.Key);
                            var targetSectionNames = pair.Value.ApplyTo.SplitAndTrim();
                            foreach (var targetSectionName in targetSectionNames)
                            {
                                if (!file.Sections.TryGetValue(targetSectionName, out AData.SectionDef targetSection))
                                {
                                    file.Sections[targetSectionName] = targetSection = new AData.SectionDef(targetSectionName)
                                    {
                                        Type = AData.SectionType.Class
                                    };
                                }

                                // move property to target section
                                targetSection.Properties[pair.Key] = pair.Value;
                            }

                            // remove apply for data
                            pair.Value.ApplyTo = null;
                        }
                    }
                }
            }

            stopwatch.Stop();
            Debug.WriteLine("Analyzed {0}", stopwatch.Elapsed.TotalMilliseconds);

            return(analytics);
        }