134 lines
8.0 KiB
HTML
134 lines
8.0 KiB
HTML
<!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><!</codesp>
|
||
после чего идет тип тега, и заканчивается
|
||
<codesp>></codesp>
|
||
. Например
|
||
<codesp><!L someLinkName></codesp>
|
||
. Этот тег - тег ссылки с идентификатором. При компиляции документа она попытается найти определение для своего
|
||
идентификатора и вставить его содержащийся текст вместо себя.
|
||
</p>
|
||
<p>
|
||
Есть два типа тегов по окончанию: те, которые заканчиваются на своем же объявлении, например Link tag (
|
||
<codesp><!L></codesp>
|
||
), и те которые нужно закрыть таким же тегом. Таким тегом является тег определения (Define tag). Он объявляется
|
||
таким же образом, как Link tag:
|
||
<codesp><!D someLinkName></codesp>
|
||
, но его нужно так же закрыть, используя
|
||
<codesp><!D></codesp>
|
||
. Между головой и хвостом тега заключается текст, который он определяет.
|
||
</p>
|
||
<p>
|
||
Например, тут тег
|
||
<codesp><!D someLinkName></codesp>
|
||
определяет текст "qwerty text", а
|
||
<codesp><!L someLinkName></codesp>
|
||
вставляет его.
|
||
</p>
|
||
<pre><code class="language-csharp"><!L someLinkName><!L someLinkName><!L someLinkName>
|
||
<!D someLinkName>qwerty text<!D></code></pre>
|
||
<p>При компиляции такого документа шаблона на выходе получится
|
||
<codesp>qwerty textqwerty textqwerty text</codesp>
|
||
потому что были прописаны 3 ссылки на одно и то же определение
|
||
</p>
|
||
<p>Последним компонентом этой библиотеки является Insert tag. Он обозначается как
|
||
<codesp><!I></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"><!I someInsertName r sep nextLine><!D nextLine>
|
||
<!D></code></pre>
|
||
|
||
</main>
|
||
<footer>
|
||
<p>© 2025 Моя страница. Наверное какие-то права защищены!!! <span id="random-emoji"></span></p>
|
||
</footer>
|
||
|
||
<script src="scripts.js"></script>
|
||
</body>
|
||
</html> |