Beispiel #1
0
        public static List <KeyValuePair <string, ClangTidyProperties> > ParseConfigurationChain(string ClangTidyFile)
        {
            List <KeyValuePair <string, ClangTidyProperties> > Result = new List <KeyValuePair <string, ClangTidyProperties> >();

            Result.Add(new KeyValuePair <string, ClangTidyProperties>(null, ClangTidyProperties.RootProperties));

            foreach (string P in Utility.SplitPath(ClangTidyFile).Reverse())
            {
                if (!Utility.HasClangTidyFile(P))
                {
                    continue;
                }

                string ConfigFile = Path.Combine(P, ".clang-tidy");

                using (StreamReader Reader = new StreamReader(ConfigFile))
                {
                    Deserializer        D        = new Deserializer(namingConvention: new PascalCaseNamingConvention());
                    ClangTidyYaml       Y        = D.Deserialize <ClangTidyYaml>(Reader);
                    ClangTidyProperties Parent   = Result[Result.Count - 1].Value;
                    ClangTidyProperties NewProps = new ClangTidyProperties(Parent);
                    SetPropertiesFromYaml(Y, NewProps);
                    Result.Add(new KeyValuePair <string, ClangTidyProperties>(P, NewProps));
                }
            }
            return(Result);
        }
Beispiel #2
0
        public static void SerializeClangTidyFile(ClangTidyProperties Props, string ClangTidyFilePath)
        {
            List <string> CommandList = new List <string>();

            SerializeCheckTree(CommandList, Props.GetCheckTree(), TreeLevelOp.Inherit);

            CommandList.Sort((x, y) =>
            {
                bool LeftSub  = x.StartsWith("-");
                bool RightSub = y.StartsWith("-");
                if (LeftSub && !RightSub)
                {
                    return(-1);
                }
                if (RightSub && !LeftSub)
                {
                    return(1);
                }
                return(StringComparer.CurrentCulture.Compare(x, y));
            });

            string ConfigFile = Path.Combine(ClangTidyFilePath, ".clang-tidy");

            using (StreamWriter Writer = new StreamWriter(ConfigFile))
            {
                Serializer    S    = new Serializer(namingConvention: new PascalCaseNamingConvention());
                ClangTidyYaml Yaml = new ClangTidyYaml();
                Yaml.Checks = String.Join(",", CommandList.ToArray());
                S.Serialize(Writer, Yaml);
            }
        }
        public static void SerializeClangTidyFile(ClangTidyProperties Props, string ClangTidyFilePath)
        {
            List<string> CommandList = new List<string>();
            SerializeCheckTree(CommandList, Props.GetCheckTree(), TreeLevelOp.Inherit);

            CommandList.Sort((x, y) =>
            {
                bool LeftSub = x.StartsWith("-");
                bool RightSub = y.StartsWith("-");
                if (LeftSub && !RightSub)
                    return -1;
                if (RightSub && !LeftSub)
                    return 1;
                return StringComparer.CurrentCulture.Compare(x, y);
            });

            string ConfigFile = Path.Combine(ClangTidyFilePath, ".clang-tidy");
            using (StreamWriter Writer = new StreamWriter(ConfigFile))
            {
                Serializer S = new Serializer(namingConvention: new PascalCaseNamingConvention());
                ClangTidyYaml Yaml = new ClangTidyYaml();
                Yaml.Checks = String.Join(",", CommandList.ToArray());
                S.Serialize(Writer, Yaml);
            }
        }
Beispiel #4
0
        private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
        {
            ClangTidyProperties Props = (ClangTidyProperties)propertyGrid1.SelectedObject;

            Props.SetHasUnsavedChanges(true);

            // When a CategoryVerb is selected, perform the corresponding action.
            PropertyDescriptor Property = e.ChangedItem.PropertyDescriptor;

            if (!(e.ChangedItem.Value is CategoryVerb))
            {
                return;
            }

            CategoryVerb Action = (CategoryVerb)e.ChangedItem.Value;

            if (Action == CategoryVerb.None)
            {
                return;
            }

            var Category = Property.Attributes.OfType <CategoryAttribute>().FirstOrDefault();

            if (Category == null)
            {
                return;
            }
            var SameCategoryProps = Props.GetProperties(new Attribute[] { Category });

            foreach (PropertyDescriptor P in SameCategoryProps)
            {
                if (P == Property)
                {
                    continue;
                }
                switch (Action)
                {
                case CategoryVerb.Disable:
                    P.SetValue(propertyGrid1.SelectedObject, false);
                    break;

                case CategoryVerb.Enable:
                    P.SetValue(propertyGrid1.SelectedObject, true);
                    break;

                case CategoryVerb.Inherit:
                    P.ResetValue(propertyGrid1.SelectedObject);
                    break;
                }
            }
            Property.ResetValue(propertyGrid1.SelectedObject);
            propertyGrid1.Invalidate();
        }
        public static CheckTree Build(ClangTidyProperties Config)
        {
            // Since some check names contain dashes in them, it doesn't make sense to
            // simply split all check names by dash and construct a huge tree.  For
            // example, in the check called google-runtime-member-string-references,
            // we don't need each of those to be a different subgroup.  So instead we
            // explicitly specify the common breaking points at which a user might want
            // to use a -* and everything else falls as a leaf under one of these
            // categories.
            // FIXME: This should be configurable without recompilation
            CheckTree Root = new CheckTree();

            string[][] Groups = new string[][] {
                new string[] { "boost" },
                new string[] { "cert" },
                new string[] { "clang", "diagnostic" },
                new string[] { "cppcoreguidelines", "interfaces" },
                new string[] { "cppcoreguidelines", "pro", "bounds" },
                new string[] { "cppcoreguidelines", "pro", "type" },
                new string[] { "google", "build" },
                new string[] { "google", "readability" },
                new string[] { "google", "runtime" },
                new string[] { "llvm" },
                new string[] { "misc" },
            };

            foreach (string[] Group in Groups)
            {
                CheckTree Subgroup = Root;
                foreach (string Component in Group)
                {
                    Subgroup = Subgroup.AddOrCreateSubgroup(Component);
                }
            }

            var Props = Config.GetProperties()
                        .Cast <PropertyDescriptor>()
                        .OfType <DynamicPropertyDescriptor <bool> >()
                        .Where(x => x.Attributes.OfType <ClangTidyCheckAttribute>().Count() > 0)
                        .Select(x => new KeyValuePair <DynamicPropertyDescriptor <bool>, string>(
                                    x, x.Attributes.OfType <ClangTidyCheckAttribute>().First().CheckName));
            var PropArray = Props.ToArray();

            foreach (var CheckInfo in PropArray)
            {
                string    LeafName = null;
                CheckTree Tree     = Root.LocateCheckLeafGroup(CheckInfo.Value, out LeafName);
                Tree.AddLeaf(LeafName, CheckInfo.Key);
            }
            return(Root);
        }
Beispiel #6
0
        private static void SetPropertiesFromYaml(ClangTidyYaml Yaml, ClangTidyProperties Props)
        {
            string[] CheckCommands = Yaml.Checks.Split(',');
            foreach (string Command in CheckCommands)
            {
                if (Command == null || Command.Length == 0)
                {
                    continue;
                }
                bool   Add     = true;
                string Pattern = Command;
                if (Pattern[0] == '-')
                {
                    Pattern = Pattern.Substring(1);
                    Add     = false;
                }

                foreach (var Match in CheckDatabase.Checks.Where(x => Utility.MatchWildcardString(x.Name, Pattern)))
                {
                    Props.SetDynamicValue(Match.Name, Add);
                }
            }
        }
Beispiel #7
0
        /// <summary>
        /// After a new configuration file is chosen, analyzes the directory hierarchy
        /// and finds all .clang-tidy files in the path, parses them and updates the
        /// PropertyGrid and quick-access LinkLabel control to reflect the new property
        /// chain.
        /// </summary>
        private void reloadPropertyChain()
        {
            StringBuilder LinkBuilder = new StringBuilder();

            LinkBuilder.Append(DefaultText);
            LinkBuilder.Append(" > ");
            int PrefixLength = LinkBuilder.Length;

            if (PropertyChain_.Count == 1)
            {
                LinkBuilder.Append(BrowseText);
            }
            else
            {
                LinkBuilder.Append(PropertyChain_[PropertyChain_.Count - 1].Key);
            }

            linkLabelPath.Text = LinkBuilder.ToString();

            // Given a path like D:\Foo\Bar\Baz, construct a LinkLabel where individual
            // components of the path are clickable iff they contain a .clang-tidy file.
            // Clicking one of the links then updates the PropertyGrid to display the
            // selected .clang-tidy file.
            ClangTidyProperties LastProps = ClangTidyProperties.RootProperties;

            linkLabelPath.Links.Clear();
            linkLabelPath.Links.Add(0, DefaultText.Length, LastProps);
            foreach (var Prop in PropertyChain_.Skip(1))
            {
                LastProps = Prop.Value;
                string ClangTidyFolder       = Path.GetFileName(Prop.Key);
                int    ClangTidyFolderOffset = Prop.Key.Length - ClangTidyFolder.Length;
                linkLabelPath.Links.Add(PrefixLength + ClangTidyFolderOffset, ClangTidyFolder.Length, LastProps);
            }
            propertyGrid1.SelectedObject = LastProps;
        }
        public static List<KeyValuePair<string, ClangTidyProperties>> ParseConfigurationChain(string ClangTidyFile)
        {
            List<KeyValuePair<string, ClangTidyProperties>> Result = new List<KeyValuePair<string, ClangTidyProperties>>();
            Result.Add(new KeyValuePair<string, ClangTidyProperties>(null, ClangTidyProperties.RootProperties));

            foreach (string P in Utility.SplitPath(ClangTidyFile).Reverse())
            {
                if (!Utility.HasClangTidyFile(P))
                    continue;

                string ConfigFile = Path.Combine(P, ".clang-tidy");

                using (StreamReader Reader = new StreamReader(ConfigFile))
                {
                    Deserializer D = new Deserializer(namingConvention: new PascalCaseNamingConvention());
                    ClangTidyYaml Y = D.Deserialize<ClangTidyYaml>(Reader);
                    ClangTidyProperties Parent = Result[Result.Count - 1].Value;
                    ClangTidyProperties NewProps = new ClangTidyProperties(Parent);
                    SetPropertiesFromYaml(Y, NewProps);
                    Result.Add(new KeyValuePair<string, ClangTidyProperties>(P, NewProps));
                }
            }
            return Result;
        }
Beispiel #9
0
 static ClangTidyProperties()
 {
     RootProperties_ = new ClangTidyProperties(null);
 }
Beispiel #10
0
        private void linkLabelPath_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            ClangTidyProperties Props = (ClangTidyProperties)e.Link.LinkData;

            propertyGrid1.SelectedObject = Props;
        }
 static ClangTidyProperties()
 {
     RootProperties_ = new ClangTidyProperties(null);
 }
        private static void SetPropertiesFromYaml(ClangTidyYaml Yaml, ClangTidyProperties Props)
        {
            string[] CheckCommands = Yaml.Checks.Split(',');
            foreach (string Command in CheckCommands)
            {
                if (Command == null || Command.Length == 0)
                    continue;
                bool Add = true;
                string Pattern = Command;
                if (Pattern[0] == '-')
                {
                    Pattern = Pattern.Substring(1);
                    Add = false;
                }

                foreach (var Match in CheckDatabase.Checks.Where(x => Utility.MatchWildcardString(x.Name, Pattern)))
                {
                    Props.SetDynamicValue(Match.Name, Add);
                }
            }
        }
        public static CheckTree Build(ClangTidyProperties Config)
        {
            // Since some check names contain dashes in them, it doesn't make sense to
            // simply split all check names by dash and construct a huge tree.  For
            // example, in the check called google-runtime-member-string-references,
            // we don't need each of those to be a different subgroup.  So instead we
            // explicitly specify the common breaking points at which a user might want
            // to use a -* and everything else falls as a leaf under one of these
            // categories.
            // FIXME: This should be configurable without recompilation
            CheckTree Root = new CheckTree();
            string[][] Groups = new string[][] {
                new string[] {"boost"},
                new string[] {"cert"},
                new string[] {"clang", "diagnostic"},
                new string[] {"cppcoreguidelines", "interfaces"},
                new string[] {"cppcoreguidelines", "pro", "bounds"},
                new string[] {"cppcoreguidelines", "pro", "type"},
                new string[] {"google", "build"},
                new string[] {"google", "readability"},
                new string[] {"google", "runtime"},
                new string[] {"llvm"},
                new string[] {"misc"},
            };

            foreach (string[] Group in Groups)
            {
                CheckTree Subgroup = Root;
                foreach (string Component in Group)
                    Subgroup = Subgroup.AddOrCreateSubgroup(Component);
            }

            var Props = Config.GetProperties()
                              .Cast<PropertyDescriptor>()
                              .OfType<DynamicPropertyDescriptor<bool>>()
                              .Where(x => x.Attributes.OfType<ClangTidyCheckAttribute>().Count() > 0)
                              .Select(x => new KeyValuePair<DynamicPropertyDescriptor<bool>, string>(
                                            x, x.Attributes.OfType<ClangTidyCheckAttribute>().First().CheckName));
            var PropArray = Props.ToArray();
            foreach (var CheckInfo in PropArray)
            {
                string LeafName = null;
                CheckTree Tree = Root.LocateCheckLeafGroup(CheckInfo.Value, out LeafName);
                Tree.AddLeaf(LeafName, CheckInfo.Key);
            }
            return Root;
        }