Files
micialware.ru/mroacgt.html
T
2025-06-13 22:01:46 +03:00

134 lines
8.0 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>mROA.CodegenTools</title>
<link rel="shortcut icon" href="img/icon.png" type="image/png">
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/tokyo-night-dark.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/csharp.min.js"></script>
<style>
main p {
font-size: large;
}
</style>
<script>hljs.highlightAll();</script>
</head>
<body>
<header>
<nav>
<ul>
<li><a href="index.html" class="brand">Micialware</a></li>
<li><a href="flagships.html">Флагманы</a></li>
<li><a href="index.html#projects">Другие проекты</a></li>
<li><a href="services.html">Услуги</a></li>
<li><a href="https://github.com/YaslePoy" class="github-link" target="_blank"><img
src="img/github-mark-white.svg" alt="GitHub">GitHub</a></li>
</ul>
</nav>
<h1>mROA.CodegenTools</h1>
<h2 class="no-margin">Как робин для RPC-бэтмена</h2>
</header>
<main>
<p>Чтож, если говорить о кодгене в C# при помощи Roslyn, то тут все не так шикарно, как могло бы быть в других
областях программировании. Ну по крайне мерее официально по примерам от Microsoft предлагается использовать
просто интерполяцию строк.</p>
<pre><code class="language-csharp">
// Build up the source code
var code = $@"// <auto-generated/>
using System;
using System.Collections.Generic;
namespace {namespaceName};
partial class {className}
{{
public IEnumerable<string> Report()
{{
{string.Join("\n", methodBody)}
}}
}}
";
// Add the source code to the compilation.
context.AddSource($"{className}.g.cs", SourceText.From(code, Encoding.UTF8));
</code></pre>
<p>
И этот метод вполне себе на самом деле рабочий. Надежный, как швейцарские часы. Но после того как я сделал так
весь кодген для mROA, вышестоящий сказал что это не читабельно, и не только из-за того, как это написано, но и в
большей части из-за использования таких иногда огромных литералов. В связи с этим созрел план, как это все можно
убрать в файлики, которые лежат где-то там, и при помощи которых можно убрать большинство огромных литералов для
работы
с текстом в контексте генерации кода.
</p>
<p>
Синтаксис mROA.CGT шаблонов основан на супер упрощенной, версии xml из параллельной вселенной и немного
перекликается с шаблонами T4. Однако в отличие от T4, код исполняется по-нормальному в среде C# кода, а не как
то там среди генерируемого кода.
</p>
<h2>Теги</h2>
<p>Каждый тег в файле, который определяет так называемый "Документ", начинается с
<codesp>&lt;!</codesp>
после чего идет тип тега, и заканчивается
<codesp>&gt;</codesp>
. Например
<codesp>&lt;!L someLinkName&gt;</codesp>
. Этот тег - тег ссылки с идентификатором. При компиляции документа она попытается найти определение для своего
идентификатора и вставить его содержащийся текст вместо себя.
</p>
<p>
Есть два типа тегов по окончанию: те, которые заканчиваются на своем же объявлении, например Link tag (
<codesp>&lt;!L&gt;</codesp>
), и те которые нужно закрыть таким же тегом. Таким тегом является тег определения (Define tag). Он объявляется
таким же образом, как Link tag:
<codesp>&lt;!D someLinkName&gt;</codesp>
, но его нужно так же закрыть, используя
<codesp>&lt;!D&gt;</codesp>
. Между головой и хвостом тега заключается текст, который он определяет.
</p>
<p>
Например, тут тег
<codesp>&lt;!D someLinkName&gt;</codesp>
определяет текст "qwerty text", а
<codesp>&lt;!L someLinkName&gt;</codesp>
вставляет его.
</p>
<pre><code class="language-csharp">&lt;!L someLinkName&gt;&lt;!L someLinkName&gt;&lt;!L someLinkName&gt;
&lt;!D someLinkName&gt;qwerty text&lt;!D&gt;</code></pre>
<p>При компиляции такого документа шаблона на выходе получится
<codesp>qwerty textqwerty textqwerty text</codesp>
потому что были прописаны 3 ссылки на одно и то же определение
</p>
<p>Последним компонентом этой библиотеки является Insert tag. Он обозначается как
<codesp>&lt;!I&gt;</codesp>
. Он работает похоже на Link tag, но он работает динамически, а не статически. То, что этот тег должен означать
задается еще до компиляции документа. Задать содержание тега можно при помощи метода Insert у документа шаблона.
В этот тег можно вставить строку или другой тег, например тег Define.
Тег Insert может менять логику своей работы при помощи опций. Они указываются после названия через пробел.
</p>
<p>
На данный момент реализованно 2 опции: repeat и separate. Они связаны между собой и параметр separate не может
быть использован без repeat. Опция repeat позволяет не просто заменять указанный Insert тег по его имени на
строку
или другой тег, а добавлять копию этого Insert тега после выбранного неограниченное количество раз и вставлять
контент уже в него. Для использования этой опции нужно прописать после названия
<codesp>r</codesp>
</p>
<pre><code class="language-csharp">&lt;!I someInsertName r sep nextLine&gt;&lt;!D nextLine&gt;
&lt;!D&gt;</code></pre>
</main>
<footer>
<p>&copy; 2025 Моя страница. Наверное какие-то права защищены!!! <span id="random-emoji"></span></p>
</footer>
<script src="scripts.js"></script>
</body>
</html>