Skip to Content
SDKLTools.SDKСоздание правил анализа кода

Создание правил анализа кода

Подробнее о назначении механизма см. в разделе Анализ проекта.

Начало работы

  1. Запустите Visual Studio.

  2. Выберите Create a new project с типом Class Library (.NET Framework) либо Class Library (поддерживаются .NET Framework 4.6.1 и .NET Standard 2.0).

  3. Введите имя проекта. Имя проекта и библиотеки dll должны начинаться с префикса Primo.

  4. Найдите в папке Primo Studio сборку Primo.ProjectAnalyzer.Dto.dll и добавьте ее в Dependencies проекта:

    alt

  5. Создайте класс (Add ➝ Class…), который будет содержать правило. Для этого надо унаследовать интерфейс Primo.ProjectAnalyzer.IAnalysisRule.

    Каждый класс — это отдельное правило анализа.

Создание правила

Пример правила ST-PR-003, проверяющего вложенность диаграмм:

using Primo.ProjectAnalyzer.Model; using Primo.ProjectAnalyzer.Model.Serialization; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Primo.ProjectAnalyzer.Dto.Rules { /// <summary> /// ST-PR-003: Несколько уровней диаграмм /// </summary> public class StPr003 : IAnalysisRule { #region Константы /// <summary> /// Кол-во /// </summary> private const string ARG_COUNT_KEY = "Count"; /// <summary> /// Кол-во /// </summary> private const int ARG_COUNT = 2; #endregion #region Свойства контракта IAnalysisRule /// <summary> /// Код /// </summary> public string Code { get { return Properties.StPr003.Code; } } /// <summary> /// Наименование /// </summary> public string Name { get { return Properties.StPr003.Name; } } /// <summary> /// Описание /// </summary> public string Description { get { return Properties.StPr003.Recomendation; } } /// <summary> /// URL помощи /// </summary> public string HelpUrl { get { return null; } } /// <summary> /// Области /// </summary> public RuleAreas[] Areas { get { return new RuleAreas[] { RuleAreas.Process }; } } private RuleActions defaultAction = RuleActions.Error; /// <summary> /// Действие по умолчанию /// </summary> public RuleActions DefaultAction { get { return defaultAction; } set { this.defaultAction = value; } } /// <summary> /// Аргументы /// </summary> public AnalysisRuleArg[] Arguments { get; set; } #endregion #region Конструкторы /// <summary> /// Конструктор /// </summary> public StPr003() { this.Arguments = new AnalysisRuleArg[] { new AnalysisRuleArg() { Key = ARG_COUNT_KEY, Name = Properties.StPr003.Arg_Count, Value = ARG_COUNT.ToString(), RegEx = @"^\d+$" } }; } #endregion #region Методы контракта IAnalysisRule /// <summary> /// Проверка проекта /// </summary> /// <param name="project">Проект</param> /// <returns>Результат проверки</returns> public RuleResult Inspect(IRobotProject project) { return new RuleResult(); } /// <summary> /// Проверка процесса /// </summary> /// <param name="process">Процесс</param> /// <returns>Результат проверки</returns> public RuleResult Inspect(IRobotProcess process) { int mx = Int32.Parse(this.Arguments.Where(it => it.Key == ARG_COUNT_KEY).FirstOrDefault().Value); int mmx = 0; foreach (var c in process.GetAllElements()) { int cn = 0; if (c.ClassName == "LTools.Workflow.Elements.WFWorkflowContainer") { cn++; cn += CountWFs(c as SerializationContainer); } if (cn > mmx) mmx = cn; } if (mmx > mx) { return new RuleResult() { HasErrors = true, Level = this.DefaultAction, RecommendationMessage = Properties.StPr003.Recomendation, Messages = new string[] { String.Format(Properties.StPr003.Description, mmx, mx) } }; } return new RuleResult(); } private static int CountWFs(SerializationContainer cont) { int cn = 0; int mx = 0; if (cont != null) { foreach (var c in cont.Components) { cn = 0; if (c.ClassName == "LTools.Workflow.Elements.WFWorkflowContainer") { cn++; cn += CountWFs(c as SerializationContainer); } if (cn > mx) mx = cn; } } return mx; } /// <summary> /// Проверка элемента /// </summary> /// <param name="component">Элемент</param> /// <returns>Результат проверки</returns> public RuleResult Inspect(SerializationComponent component) { return new RuleResult(); } /// <summary> /// Сброс к исходным значениям /// </summary> public void Reset() { this.Arguments.Where(it => it.Key == ARG_COUNT_KEY).FirstOrDefault().Value = ARG_COUNT.ToString(); } #endregion } }

Описание классов

IAnalysisRule

Имя члена классаОписание
CodeКод правила
NameНаименование правила
DescriptionОписание правила
HelpUrlСсылка на описание
AreasОбласти, к которым применимо правило (Проект, Процесс, Элемент)
DefaultActionДействие по умолчанию (Info, Error, Warning, Verbose)
ArgumentsАргументы правила
Inspect(…)Методы, осуществляющие проверку правила
Reset()Вызывается при сбросе правила в состояние по умолчанию

AnalysisRuleArg

Имя члена классаОписание
KeyКлюч-идентификатор
NameНаименование аргумента
RegExРегулярное выражение, применяемое при проверке ввода аргумента
ValueЗначение аргумента

alt

RuleResult

Имя члена классаОписание
LevelДействие
HasErrorsПризнак наличия ошибки (для Error, Warning и Vaerbose). Info попадает в результат всегда
RecommendationMessageТекст рекомендации
MessagesСообщения

alt

Анатомия проекта Primo

IRobotProject – информация о проекте.

Имя члена классаОписание
ProjectДанные проекта
ItemsМассив файлов проекта
DependenciesМассив зависимостей проекта
GetAllProcesses()Возвращает все процессы проекта

IRobotProcess – информация о процессе.

Имя члена классаОписание
FileNameИмя файла
ProcessTypeТип процесса
IsTestCaseПризнак тестового случая
UseArgsПризнак использования аргументов
ScriptTypeТип скрипта
RootContainerКорневой контейнер (для последовательности)
ComponentsЭлементы процесса (для диаграммы)
GlobalVariablesПерменные
ArgumentsАргументы
GetAllElements()Возвращает все элементы процесса

SerializationComponent – информация об элементе.

Имя члена классаОписание
ClassNameИмя класса
AssemblyNameИмя сборки
PropertiesМассив свойств (Name – имя, Value – значение)

SerializationContainer : SerializationComponent – информация об элементе-контейнере.

Имя члена классаОписание
ComponentsМассив элементов контейнера

Сборка и отладка

Для отладки можно использовать класс Inspector.

Пример:

Primo.ProjectAnalyzer.Inspector insp = new Primo.ProjectAnalyzer.Inspector(); //Проверка проекта var proj = Primo.ProjectAnalyzer.Helper.ProcessHelper.LoadProject(@"C:\Test\project.ltp"); var ret = insp.InspectRule(proj, testrule1); //Проверка процесса var proc = Primo.ProjectAnalyzer.Helper.ProcessHelper.LoadProcess(@"C:\Test\Main.ltw"); ret = insp.InspectRule(proc, testrule2); //Проверка элемента var els = proc.GetAllElements(); ret = insp.InspectRule(els.Where(it => it.Properties.Where(it2 => (it2.Name == "ComponentID") && (it2.Value.ToString() == "20a3444a-70fe-4657-a4fa-390668af67f9")).Count() > 0).First(), testRule);

В результате сборки нового правила будет получена библиотека Primo.*.dll. Ее нужно скопировать и добавить в папку Primo Studio. Если библиотека не содержит ошибок, после запуска Студии правило станет доступно в меню Общие > Анализ.