示例#1
0
 /// <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);
     }
 }
示例#2
0
        public void Graph(DependencyRuleSet ruleSet, IEnumerable <Dependency> dependencies)
        {
            var graphAbstractions = new List <GraphAbstraction>();

            ruleSet.ExtractGraphAbstractions(graphAbstractions);
            var x = ruleSet.ExtractDependencyGroups();

            Graph(graphAbstractions, x, dependencies);
        }
示例#3
0
 /// <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
 }
示例#4
0
        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);
        }
示例#5
0
        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);
        }
示例#6
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);
        }
示例#7
0
        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);
        }