107 lines
6.1 KiB
HTML
107 lines
6.1 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>
|
|||
|
|
<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>
|
|||
|
|
</main>
|
|||
|
|
<footer>
|
|||
|
|
<p>© 2025 Моя страница. Наверное какие-то права защищены!!! <span id="random-emoji"></span></p>
|
|||
|
|
</footer>
|
|||
|
|
|
|||
|
|
<script src="scripts.js"></script>
|
|||
|
|
</body>
|
|||
|
|
</html>
|