/// <summary> /// Add one or more <c>DependencyRules</c>s from a single input /// line. /// public for testability. /// </summary> public void AddDependencyRules(DependencyRuleSet parent, string ruleFileName, uint lineNo, string line) { if (line.Contains(DependencyRuleSet.MAYUSE)) { foreach (var rule in CreateDependencyRules(parent, ruleFileName, lineNo, line, DependencyRuleSet.MAYUSE, false)) { Add(_allowed, rule); } } else if (line.Contains(DependencyRuleSet.MAYUSE_WITH_WARNING)) { foreach (var rule in CreateDependencyRules(parent, ruleFileName, lineNo, line, DependencyRuleSet.MAYUSE_WITH_WARNING, true)) { Add(_questionable, rule); } } else if (line.Contains(DependencyRuleSet.MUSTNOTUSE)) { foreach (var rule in CreateDependencyRules(parent, ruleFileName, lineNo, line, DependencyRuleSet.MUSTNOTUSE, false)) { Add(_forbidden, rule); } } else { throw new ApplicationException("Unexpected rule at " + ruleFileName + ":" + lineNo); } }
public void Graph(DependencyRuleSet ruleSet, IEnumerable <Dependency> dependencies) { var graphAbstractions = new List <GraphAbstraction>(); ruleSet.ExtractGraphAbstractions(graphAbstractions); var x = ruleSet.ExtractDependencyGroups(); Graph(graphAbstractions, x, dependencies); }
/// <summary> /// Read rule set from file. /// </summary> /// <returns>Read rule set; or <c>null</c> if not poeeible to read it.</returns> public DependencyRuleSet Load(string dependencyFilename, List <DirectoryOption> directories) { foreach (var d in directories) { string fullName = d.GetFullNameFor(dependencyFilename); if (fullName != null) { DependencyRuleSet result = Create(new DirectoryInfo("."), fullName); if (result != null) { return(result); } } } return(null); // if nothing found }
private static IEnumerable <DependencyRule> CreateDependencyRules(DependencyRuleSet parent, string ruleFileName, uint lineNo, string line, string sep, bool questionableRule) { DependencyRuleRepresentation rep = new DependencyRuleRepresentation(ruleFileName, lineNo, line, questionableRule); int i = line.IndexOf(sep); string usingPattern = parent.ExpandDefines(line.Substring(0, i).Trim()); string usedPattern = parent.ExpandDefines(line.Substring(i + sep.Length).Trim()); List <DependencyRule> deps = DependencyRule.CreateDependencyRules(usingPattern, usedPattern, rep); if (Log.IsVerboseEnabled) { Log.WriteInfo(String.Format("Rules used for checking {0} ({1}:{2})", line, ruleFileName, lineNo)); foreach (DependencyRule d in deps) { Log.WriteInfo(" " + d); } } return(deps); }
private int AnalyzeAssembly(CheckerContext checkerContext, string assemblyFilename) { var dependencyFilename = Path.GetFileName(assemblyFilename) + ".dep"; try { Log.WriteInfo("Analyzing " + assemblyFilename); using (var assemblyContext = checkerContext.OpenAssemblyContext(Path.GetFileName(assemblyFilename))) { DependencyRuleSet ruleSetForAssembly = checkerContext.Load(dependencyFilename, _options.Directories); if (ruleSetForAssembly == null && !String.IsNullOrEmpty(_options.DefaultRuleSetFile)) { ruleSetForAssembly = checkerContext.Create(new DirectoryInfo("."), _options.DefaultRuleSetFile); } if (ruleSetForAssembly == null) { Log.WriteError(dependencyFilename + " not found in -d and -s directories, and no default rule set provided by -x"); return(6); } else { try { IEnumerable <Dependency> dependencies = DependencyReader.GetDependencies(assemblyFilename); IEnumerable <DependencyRuleGroup> groups = ruleSetForAssembly.ExtractDependencyGroups(); bool success = _checker.Check(assemblyContext, groups, dependencies, _options.ShowUnusedQuestionableRules); if (!success) { return(3); } if (_options.DotFilename != null) { _grapher.Graph(ruleSetForAssembly, dependencies); } } catch (FileNotFoundException ex) { Log.WriteError("Input file " + ex.FileName + " not found"); return(4); } } } } catch (FileLoadException ex2) { Log.WriteError(ex2.Message); return(2); } return(0); }
public DependencyRuleSet Create(DirectoryInfo relativeRoot, string rulefilename, IDictionary <string, string> defines, IDictionary <string, DependencyRuleSet.Macro> macros) { string fullRuleFilename = Path.Combine(relativeRoot.FullName, rulefilename); DependencyRuleSet result; if (!_fullFilename2RulesetCache.TryGetValue(fullRuleFilename, out result)) { try { long start = Environment.TickCount; result = new DependencyRuleSet(this, fullRuleFilename, defines, macros); Log.WriteDebug("Completed reading " + fullRuleFilename + " in " + (Environment.TickCount - start) + " ms"); _fullFilename2RulesetCache.Add(fullRuleFilename, result); } catch (FileNotFoundException) { Log.WriteError("File " + fullRuleFilename + " not found"); return(null); } } return(result); }
private bool ProcessText(string fullRuleFilename, uint startLineNo, TextReader tr, string leftParam, string rightParam) { uint lineNo = startLineNo; bool textIsOk = true; DependencyRuleGroup currentGroup = _mainRuleGroup; for (; ;) { string line = tr.ReadLine(); if (line == null) { break; } line = line.Trim().Replace(LEFT_PARAM, leftParam).Replace(RIGHT_PARAM, rightParam); lineNo++; if (line == "" || line.StartsWith("#") || line.StartsWith("//")) { // ignore; } else if (line.StartsWith("+")) { string includeFilename = line.Substring(1).Trim(); DependencyRuleSet included = _checkerContext.Create(new FileInfo(fullRuleFilename).Directory, includeFilename, _defines, _macros); if (included != null) { // Error message when == null has been output by Create. _includedRuleSets.Add(included); // We copy the defines down into the ruleset so that the selection // of the longest name works (_defines implements this by using // a SortedDictionary with a LengthComparer). foreach (var kvp in included._defines) { _defines[kvp.Key] = kvp.Value; } foreach (var kvp in included._macros) { _macros[kvp.Key] = kvp.Value; } } } else if (line.EndsWith("{")) { if (currentGroup.Group != "") { Log.WriteError(String.Format("{0}: Nested '... {{' not possible", fullRuleFilename), fullRuleFilename, lineNo); } else { currentGroup = new DependencyRuleGroup(line.TrimEnd('{').TrimEnd()); _ruleGroups.Add(currentGroup); } } else if (line == "}") { if (currentGroup.Group != "") { currentGroup = _mainRuleGroup; } else { Log.WriteError(String.Format("{0}: '}}' without corresponding '... {{'", fullRuleFilename), fullRuleFilename, lineNo); } } else if (ProcessMacroIfFound(line)) { // macro is already processed as side effect in ProcessMacroIfFound() } else if (line.Contains(MAYUSE) || line.Contains(MUSTNOTUSE) || line.Contains(MAYUSE_WITH_WARNING)) { currentGroup.AddDependencyRules(this, fullRuleFilename, lineNo, line); } else if (line.StartsWith(GRAPHIT)) { AddGraphAbstractions(fullRuleFilename, lineNo, line); } else if (line.EndsWith(MACRO_DEFINE)) { string macroName = line.Substring(0, line.Length - MACRO_DEFINE.Length).Trim(); if (!CheckDefinedName(macroName, fullRuleFilename, lineNo)) { textIsOk = false; } string macroText = ""; uint macroStartLineNo = lineNo; for (; ;) { line = tr.ReadLine(); lineNo++; if (line == null) { Log.WriteError(String.Format("{0}: Missing {1} at end", fullRuleFilename, MACRO_END), fullRuleFilename, lineNo); textIsOk = false; break; } line = line.Trim(); if (line == MACRO_END) { var macro = new Macro(macroText, fullRuleFilename, macroStartLineNo); if (_macros.ContainsKey(macroName) && !_macros[macroName].Equals(macro)) { throw new ApplicationException("Macro '" + macroName + "' cannot be redefined differently at " + fullRuleFilename + ":" + lineNo); } _macros[macroName] = macro; break; } else { macroText += line + "\n"; } } } else if (line.Contains(DEFINE)) { AddDefine(fullRuleFilename, lineNo, line); } else { Log.WriteError(fullRuleFilename + ": Cannot parse line " + lineNo + ": " + line, fullRuleFilename, lineNo); textIsOk = false; } } return(textIsOk); }