public UniqueProjectRule(Func<Project, bool> filter, Func<Project, string> id, Func<Project, string> description, Severity severity,
     ConfigLocation location)
     : base(severity, location)
 {
     this.filter = filter;
     this.id = id;
     this.description = description;
 }
 private static OutputMessage CreateMessage(string type, ConfigLocation location)
 {
     return new OutputMessage().Append("The ")
         .Append(type)
         .Append(" defined in ")
         .Append(location.LineNum)
         .Append(" of config file is never used: ")
         .Append(location.LineText);
 }
 public DepenendencyRule(Severity severity, LibraryMatcher source, LibraryMatcher target, DependencyMatcher dependency, bool allow,
     ConfigLocation location)
     : base(severity, location)
 {
     Source = source ?? ((l, r) => true);
     Target = target ?? ((l, r) => true);
     Dependency = dependency ?? ((d, r) => true);
     Allow = allow;
 }
Exemple #4
0
 public Ignore(LibraryMatcher matches, ConfigLocation location)
 {
     Matches = matches;
     Location = location;
 }
 public LibraryMatcher ParseLibraryMatcher(string matchLine, ConfigLocation location)
 {
     return ParseInternediaryLibraryMatcher(matchLine, location)
         .Finalize();
 }
        private void ParseRule(string line, ConfigLocation location)
        {
            var severity = Severity.Error;
            DependencyMatcher dependencyFilter = null;

            if (line.EndsWith("]"))
            {
                var start = line.LastIndexOf("[", StringComparison.InvariantCulture);
                var details = line.Substring(start + 1, line.Length - start - 2);
                line = line.Substring(0, start)
                    .Trim();

                foreach (var detail in details.Split(',')
                    .Select(d => d.Trim()))
                {
                    Severity tmp;
                    if (severities.TryGetValue(detail.ToLower(), out tmp))
                        severity = tmp;
                    else
                        dependencyFilter = dependencyFilter.And(ParseDependencyMatcher(detail, location));
                }
            }

            var factory = customRules.Get(line.ToLower());
            if (factory != null)
            {
                config.Rules.Add(factory(location, severity, dependencyFilter));
                return;
            }

            if (ParseRule(line, location, NOT_DEPENDS, severity, dependencyFilter))
                return;

            if (ParseRule(line, location, DEPENDS, severity, dependencyFilter))
                return;

            throw new ConfigParserException(location, "Invalid rule");
        }
 private void ParseOutputProjects(string line, ConfigLocation location)
 {
     config.Output.Projects.Add(PathUtils.ToAbsolute(basePath, line));
 }
        private void ParseOutputArchitecture(string line, ConfigLocation location)
        {
            var file = PathUtils.ToAbsolute(basePath, line);
            var extension = Path.GetExtension(file) ?? "";

            if (extension.Equals(".xml", StringComparison.CurrentCultureIgnoreCase))
                config.Output.Architecture.Add(new XMLArchitectureOutputer(file));
            else if (extension.Equals(".dot", StringComparison.CurrentCultureIgnoreCase))
                config.Output.Architecture.Add(new DotArchitectureOutputer(file));
            else
                config.Output.Architecture.Add(new TextArchitectureOutputer(file));
        }
        private InternediaryLibraryMatcher ParseInternediaryLibraryMatcher(string matchLine, ConfigLocation location)
        {
            InternediaryLibraryMatcher result = null;

            var lineTypes = new Dictionary<string, Action<string, ConfigLocation>>
            {
                {
                    "not:", (line, loc) =>
                    {
                        InternediaryLibraryMatcher matcher = ParseInternediaryLibraryMatcher(line, loc);
                        result = (library, reporter) => !matcher(library, (f, v, m) => reporter(f, v, !m));
                    }
                },
                {
                    "local:", (line, loc) => result = Matchers.Projects.Place(true)
                        .And(ParseInternediaryLibraryMatcher(line, loc))
                },
                {
                    "non local:", (line, loc) => result = Matchers.Projects.Place(false)
                        .And(ParseInternediaryLibraryMatcher(line, loc))
                },
                {
                    "project:", (line, loc) => result = Matchers.Projects.Type(true)
                        .And(ParseInternediaryLibraryMatcher(line, loc))
                },
                {
                    "lib:", (line, loc) => result = Matchers.Projects.Type(false)
                        .And(ParseInternediaryLibraryMatcher(line, loc))
                },
                { "regex:", (line, loc) => result = Matchers.Projects.NameRE(line) },
                { "path:", (line, loc) => result = Matchers.Projects.Path(basePath, line) },
                { "path regex:", (line, loc) => result = Matchers.Projects.PathRE(line) },
                { "lang:", (line, loc) => result = Matchers.Projects.Language(line) },
                { "", (line, loc) => result = Matchers.Projects.Name(line) },
            };

            ParseLine(lineTypes, matchLine, location);

            return result;
        }
 private void ParseInput(string line, ConfigLocation configLocation)
 {
     string absolute = PathUtils.ToAbsolute(basePath, line);
     config.Inputs.Add(PathUtils.RemoveSeparatorAtEnd(absolute));
 }
 public NoCircularDepenendenciesRule(Severity severity, ConfigLocation location)
     : base(severity, location)
 {
 }
 public UnusedConfigOutputEntry(string type, ConfigLocation location)
     : base("Config/Unused " + type, Severity.Info, CreateMessage(type, location))
 {
     Location = location;
 }
 public ConfigParserException(ConfigLocation location, string message)
     : this(string.Format("{0} in line {1}: {2}", message, location.LineNum, location.LineText))
 {
 }
        private void ParseIgnore(string line, ConfigLocation location)
        {
            var matcher = ParseLibraryMatcher(line, location);

            config.Ignores.Add(new Config.Ignore(matcher, location));
        }
 protected BaseRule(Severity severity, ConfigLocation location)
 {
     Severity = severity;
     Location = location;
 }
        private void ParseInOutput(string line, ConfigLocation location)
        {
            if (line == "ignore loading infos")
                config.InOutput.Ignore.Add(w => w.Type.StartsWith("Loading/"));

            else if (line == "ignore config infos")
                config.InOutput.Ignore.Add(w => w.Type.StartsWith("Config/"));

            else
                throw new ConfigParserException(location, "Invalid line");
        }
 public UniqueDependenciesRule(Severity severity, DependencyMatcher filter, ConfigLocation location)
     : base(severity, location)
 {
     this.filter = filter ?? ((d, r) => true);
 }
        private InternediaryDependencyMatcher ParseInternediaryDependencyMatcher(string detail, ConfigLocation location)
        {
            InternediaryDependencyMatcher result = null;

            var lineTypes = new Dictionary<string, Action<string, ConfigLocation>>
            {
                {
                    "not:", (line, loc) =>
                    {
                        var matcher = ParseInternediaryDependencyMatcher(line, loc);
                        result = (library, reporter) => !matcher(library, (f, v, m) => reporter(f, v, !m));
                    }
                },
                { "dep:", (line, loc) => result = Matchers.Dependencies.Type(line) },
                { "dep path:", (line, loc) => result = Matchers.Dependencies.Path(basePath, line) },
                { "dep path regex:", (line, loc) => result = Matchers.Dependencies.PathRE(line) },
            };

            ParseLine(lineTypes, detail, location);

            return result;
        }
        private static NoCircularDepenendenciesRule NewNoCircularDepenendenciesRule(ConfigLocation l, Severity s, DependencyMatcher d)
        {
            if (d != null)
                throw new ConfigParserException(l, "No dependency details are possible in project rules");

            return new NoCircularDepenendenciesRule(s, l);
        }
        private void ParseLine(Dictionary<string, Action<string, ConfigLocation>> types, string line, ConfigLocation location)
        {
            var type = types.FirstOrDefault(t => t.Key == "" || line.StartsWith(t.Key));
            if (type.Value == null)
                throw new ConfigParserException(location, "Unknown line");

            var remaining = line.Substring(type.Key.Length)
                .Trim();

            if (type.Key == "" && remaining.IndexOf(':') >= 0)
                throw new ConfigParserException(location, "Invalid expression");

            try
            {
                type.Value(remaining, location);
            }
            catch (ConfigParserException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new ConfigParserException(location, e.Message);
            }
        }
        private static UniqueProjectRule NewUniqueGuidProjectRule(ConfigLocation l, Severity s, DependencyMatcher d)
        {
            if (d != null)
                throw new ConfigParserException(l, "No dependency details are possible in project rules");

            return new UniqueProjectRule(p => p.Guid != null, p => p.Guid.ToString(), p => "with GUID " + p.Guid, s, l);
        }
        // ReSharper disable once UnusedParameter.Local
        private void ParseOutputDependencies(string line, ConfigLocation location, bool onlyWithMessages)
        {
            var file = PathUtils.ToAbsolute(basePath, line);
            var extension = Path.GetExtension(file) ?? "";

            if (extension.Equals(".xml", StringComparison.CurrentCultureIgnoreCase))
                config.Output.Dependencies.Add(FilterIfNeeded(onlyWithMessages, new XMLDependenciesOutputer(file)));
            else if (extension.Equals(".dot", StringComparison.CurrentCultureIgnoreCase))
                config.Output.Dependencies.Add(FilterIfNeeded(onlyWithMessages, new DotDependenciesOutputer(file)));
            else
                config.Output.Dependencies.Add(FilterIfNeeded(onlyWithMessages, new TextDependenciesOutputer(file)));
        }
        private static UniqueProjectRule NewUniqueNameProjectRule(ConfigLocation l, Severity s, DependencyMatcher d)
        {
            if (d != null)
                throw new ConfigParserException(l, "No dependency details are possible in project rules");

            return new UniqueProjectRule(p => p.ProjectName != null, p => p.Name, p => "named " + p.Name, s, l);
        }
        private void ParseOutputResults(string line, ConfigLocation location)
        {
            if (line.Equals("console", StringComparison.CurrentCultureIgnoreCase))
                config.Output.Results.Add(new ConsoleEntryOutputer(false));

            else if (line.Equals("console verbose", StringComparison.CurrentCultureIgnoreCase))
                config.Output.Results.Add(new ConsoleEntryOutputer(true));

            else
            {
                var file = PathUtils.ToAbsolute(basePath, line);
                var extension = Path.GetExtension(file) ?? "";

                if (extension.Equals(".xml", StringComparison.CurrentCultureIgnoreCase))
                    config.Output.Results.Add(new XMLEntryOutputer(file));
                else
                    config.Output.Results.Add(new TextEntryOutputer(file));
            }
        }
 private DependencyMatcher ParseDependencyMatcher(string detail, ConfigLocation location)
 {
     return ParseInternediaryDependencyMatcher(detail, location)
         .Finalize();
 }
        private bool ParseRule(string line, ConfigLocation location, string separator, Severity severity, DependencyMatcher dependencyFilter)
        {
            var pos = line.IndexOf(separator, StringComparison.Ordinal);
            if (pos < 0)
                return false;

            var left = ParseLibraryMatcher(line.Substring(0, pos)
                .Trim(), location);
            var right = ParseLibraryMatcher(line.Substring(pos + separator.Length)
                .Trim(), location);

            config.Rules.Add(new DepenendencyRule(severity, left, right, dependencyFilter, separator == DEPENDS, location));

            return true;
        }
        private void ParseGroup(string line, ConfigLocation location)
        {
            int pos = line.IndexOf(GROUP_ELEMENT, StringComparison.CurrentCultureIgnoreCase);
            if (pos < 0)
                throw new ConfigParserException(location, "Invalid group (should contain Name " + GROUP_ELEMENT + " Contents)");

            string name = line.Substring(0, pos)
                .Trim();
            if ("<No Group>".Equals(name, StringComparison.CurrentCultureIgnoreCase))
                name = null;

            string matchLine = line.Substring(pos + DEPENDS.Length)
                .Trim();

            LibraryMatcher matcher = ParseLibraryMatcher(matchLine, location);

            config.Groups.Add(new Config.Group(name, matcher, location));
        }
        public Config ParseLines(string filename, string[] lines)
        {
            basePath = Path.GetDirectoryName(filename);
            config = new Config();

            var lineTypes = new Dictionary<string, Action<string, ConfigLocation>>
            {
                { "input:", ParseInput },
                { "group:", ParseGroup },
                { "output projects:", ParseOutputProjects },
                { "output groups:", ParseOutputGroups },
                { "output dependencies:", (line, loc) => ParseOutputDependencies(line, loc, false) },
                { "output dependencies with errors:", (line, loc) => ParseOutputDependencies(line, loc, true) },
                { "output architecture:", ParseOutputArchitecture },
                { "output results:", ParseOutputResults },
                { "rule:", ParseRule },
                { "ignore:", ParseIgnore },
                { "in output:", ParseInOutput },
            };

            var re = new Regex(@"(?<![a-zA-Z0-9])" + COMMENT, RegexOptions.IgnoreCase);

            foreach (var item in lines.Indexed())
            {
                // Line number starts in 1
                var location = new ConfigLocation(item.Index + 1, item.Item);
                var line = item.Item.Trim();

                var m = re.Match(line);
                if (m.Success)
                    line = line.Substring(0, m.Index)
                        .Trim();

                if (string.IsNullOrWhiteSpace(line))
                    continue;

                ParseLine(lineTypes, line, location);
            }

            return config;
        }
Exemple #29
0
 public Group(string name, LibraryMatcher matches, ConfigLocation location)
 {
     Name = name;
     Matches = matches;
     Location = location;
 }