{"id":483191,"date":"2026-06-10T14:28:49","date_gmt":"2026-06-10T14:28:49","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=483191"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=483191","title":{"rendered":"\u0418\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u043d\u0430 c#"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0423\u0440\u0430, \u0432\u043e\u0442 \u0438 \u0434\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c \u043c\u044b \u0434\u043e \u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430, \u0437\u0430\u0447\u0435\u043c \u043c\u044b \u0432\u043e\u043e\u0431\u0449\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0440\u043e\u0441\u043b\u0438\u043d\u043e\u0432\u043a\u0441\u043a\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0435\u0440\u0435\u0432\u0430. \u0412 \u043f\u0440\u043e\u0448\u043b\u044b\u0439 \u0440\u0430\u0437 \u043c\u044b \u0434\u043e\u0448\u043b\u0438 \u0434\u043e \u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430, \u043a\u043e\u0433\u0434\u0430 <code>.akbura<\/code> \u0444\u0430\u0439\u043b \u0443\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u0432 lossless syntax tree: \u043b\u0435\u043a\u0441\u0435\u0440 \u0447\u0438\u0442\u0430\u0435\u0442 \u0442\u043e\u043a\u0435\u043d\u044b, \u043f\u0430\u0440\u0441\u0435\u0440 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 <code>state<\/code>, <code>param<\/code>, <code>inject<\/code>, <code>useEffect<\/code>, <code>command<\/code>, markup, inline Akcss \u0438 C# fragments. \u042d\u0442\u043e \u0443\u0436\u0435 \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u044f\u0437\u044b\u043a, \u043d\u043e \u0434\u043b\u044f IDE \u044d\u0442\u043e\u0433\u043e \u043c\u0430\u043b\u043e.<\/p>\n<ol>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/970332\/\" rel=\"noopener noreferrer nofollow\">\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/1042432\/\" rel=\"noopener noreferrer nofollow\">\u041f\u0438\u0448\u0435\u043c \u043f\u0430\u0440\u0441\u0435\u0440<\/a><\/p>\n<\/li>\n<li>\n<p><strong>\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0431\u043b\u0435\u043d\u0434\u0435\u0440<\/strong><\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0443<\/p>\n<\/li>\n<li>\n<p>\u0414\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0430<\/p>\n<\/li>\n<li>\n<p>\u0418\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u043c Language Server Protocol \u0438 \u0434\u0435\u043b\u0430\u0435\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0432 Visual Studio<\/p>\n<\/li>\n<li>\n<p>\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434<\/p>\n<\/li>\n<\/ol>\n<h2>\u0417\u0430\u0447\u0435\u043c \u043d\u0443\u0436\u0435\u043d \u0431\u043b\u0435\u043d\u0434\u0435\u0440<\/h2>\n<p>\u041e\u0431\u044b\u0447\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u044f\u043c\u043e\u043b\u0438\u043d\u0435\u0439\u043d\u043e. \u0415\u043c\u0443 \u0434\u0430\u044e\u0442 \u0442\u0435\u043a\u0441\u0442, \u043e\u043d \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043b\u0435\u043a\u0441\u0435\u0440, \u043b\u0435\u043a\u0441\u0435\u0440 \u043e\u0442\u0434\u0430\u0451\u0442 \u0442\u043e\u043a\u0435\u043d\u044b, \u043f\u0430\u0440\u0441\u0435\u0440 \u0441\u0442\u0440\u043e\u0438\u0442 \u0434\u0435\u0440\u0435\u0432\u043e. \u0415\u0441\u043b\u0438 \u0444\u0430\u0439\u043b \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439, \u044d\u0442\u043e \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e. \u0415\u0441\u043b\u0438 \u0444\u0430\u0439\u043b \u0431\u043e\u043b\u044c\u0448\u043e\u0439, \u0442\u043e\u0436\u0435 \u0442\u0435\u0440\u043f\u0438\u043c\u043e. \u041d\u043e IDE \u0436\u0438\u0432\u0451\u0442 \u0432 \u0434\u0440\u0443\u0433\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435.<\/p>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0444\u0430\u0439\u043b \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u0438 \u043d\u0435 \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u0442 \u043a\u043d\u043e\u043f\u043a\u0443 <code>Parse<\/code>. \u041e\u043d \u043f\u0435\u0447\u0430\u0442\u0430\u0435\u0442. \u041f\u043e\u0442\u043e\u043c \u0441\u0442\u0438\u0440\u0430\u0435\u0442. \u041f\u043e\u0442\u043e\u043c \u0441\u043d\u043e\u0432\u0430 \u043f\u0435\u0447\u0430\u0442\u0430\u0435\u0442. \u0418\u043d\u043e\u0433\u0434\u0430 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u0441\u0438\u043c\u0432\u043e\u043b \u0432 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u0444\u0430\u0439\u043b\u0430:<\/p>\n<pre><code class=\"cs\">state int count = 0;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0442\u0430\u043b\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">state int total = 0;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u044d\u0442\u043e \u043d\u043e\u0432\u044b\u0439 \u0442\u0435\u043a\u0441\u0442. \u0417\u043d\u0430\u0447\u0438\u0442 \u043c\u043e\u0436\u043d\u043e \u0441\u043d\u043e\u0432\u0430 \u043f\u0440\u043e\u0439\u0442\u0438 \u0432\u0435\u0441\u044c \u0444\u0430\u0439\u043b \u043e\u0442 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430 \u0434\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e. \u041d\u043e \u0435\u0441\u043b\u0438 \u0432 \u0444\u0430\u0439\u043b\u0435 \u0442\u044b\u0441\u044f\u0447\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, markup \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u043a\u0440\u0430\u043d\u043e\u0432, inline Akcss \u0438 \u043a\u0443\u0447\u0430 C# blocks, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0430\u043d\u043d\u0430\u044f \u043a\u0430\u0440\u0442\u0438\u043d\u0430: \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0438\u0437\u043c\u0435\u043d\u0438\u043b <code>count<\/code>, \u0430 \u043c\u044b \u0437\u0430\u043d\u043e\u0432\u043e \u0441\u0442\u0440\u043e\u0438\u043c \u0432\u0441\u0451 \u0434\u0435\u0440\u0435\u0432\u043e.<\/p>\n<p>\u0412 \u043e\u0431\u044b\u0447\u043d\u043e\u043c compiler pipeline \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u043e. \u0412 IDE \u044d\u0442\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u043c\u0435\u0448\u0430\u0442\u044c. \u041f\u043e\u0434\u0441\u0432\u0435\u0442\u043a\u0430, diagnostics, completion, semantic model \u2014 \u0432\u0441\u0451 \u044d\u0442\u043e \u0437\u0430\u0432\u044f\u0437\u0430\u043d\u043e \u043d\u0430 \u0447\u0430\u0441\u0442\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u0435\u0440\u0435\u0432\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0438 \u043f\u0435\u0440\u0435\u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0443 \u0447\u0430\u0441\u0442\u044c, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u0437\u0430\u0442\u0440\u043e\u043d\u0443\u043b\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0412\u043e\u0442 \u0437\u0434\u0435\u0441\u044c \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u043b\u0435\u043d\u0434\u0435\u0440.<\/p>\n<p>\u0418\u0434\u0435\u044f \u0431\u043b\u0435\u043d\u0434\u0435\u0440\u0430 \u043f\u0440\u043e\u0441\u0442\u0430\u044f: \u043f\u0430\u0440\u0441\u0435\u0440 \u0432\u0441\u0451 \u0435\u0449\u0451 \u0445\u043e\u0447\u0435\u0442 \u043b\u0438\u043d\u0435\u0439\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a. \u041e\u043d \u043d\u0435 \u0445\u043e\u0447\u0435\u0442 \u0434\u0443\u043c\u0430\u0442\u044c, \u043e\u0442\u043a\u0443\u0434\u0430 \u043f\u0440\u0438\u0448\u0451\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442. \u0420\u0430\u043d\u044c\u0448\u0435 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0431\u044b\u043b \u043e\u0434\u0438\u043d \u2014 \u043b\u0435\u043a\u0441\u0435\u0440. \u0422\u0435\u043f\u0435\u0440\u044c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432 \u0434\u0432\u0430:<\/p>\n<pre><code>\u0441\u0442\u0430\u0440\u043e\u0435 syntax tree  =&gt; \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0435 \u0443\u0437\u043b\u044b \u0438 \u0442\u043e\u043a\u0435\u043d\u044b\u043d\u043e\u0432\u044b\u0439 SourceText    =&gt; \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u043d\u043e\u0432\u043e \u043b\u0435\u043a\u0441\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0451\u043d\u043d\u044b\u0435 \u043c\u0435\u0441\u0442\u0430<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0411\u043b\u0435\u043d\u0434\u0435\u0440 \u0441\u0442\u043e\u0438\u0442 \u043c\u0435\u0436\u0434\u0443 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u043c, \u043b\u0435\u043a\u0441\u0435\u0440\u043e\u043c \u0438 \u0441\u0442\u0430\u0440\u044b\u043c \u0434\u0435\u0440\u0435\u0432\u043e\u043c. \u041f\u0430\u0440\u0441\u0435\u0440 \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442: \u0434\u0430\u0439 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d \u0438\u043b\u0438 node. \u0411\u043b\u0435\u043d\u0434\u0435\u0440 \u0441\u043c\u043e\u0442\u0440\u0438\u0442 \u043d\u0430 \u043f\u043e\u0437\u0438\u0446\u0438\u044e, \u0441\u043c\u043e\u0442\u0440\u0438\u0442 \u043d\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438 \u0440\u0435\u0448\u0430\u0435\u0442:<\/p>\n<pre><code>\u0435\u0441\u043b\u0438 \u0441\u0442\u0430\u0440\u044b\u0439 \u0443\u0437\u0435\u043b \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u0435\u043d =&gt; \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0439 \u0443\u0437\u0435\u043b\u0435\u0441\u043b\u0438 \u043c\u0435\u0441\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u043e\u0441\u044c      =&gt; \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0432\u0435\u0436\u0438\u0439 token \u0438\u0437 lexer-\u0430<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0443\u0434\u0430\u0447\u043d\u043e\u0435. \u041e\u043d \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043c\u0435\u0448\u0438\u0432\u0430\u0435\u0442 \u0441\u0442\u0430\u0440\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 \u0438 \u043d\u043e\u0432\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0442\u043e\u043a\u0435\u043d\u043e\u0432.<\/p>\n<h2>TextChangeRange<\/h2>\n<p>\u041d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0432\u0441\u0451 \u0441 <a href=\"https:\/\/learn.microsoft.com\/ru-ru\/dotnet\/api\/microsoft.codeanalysis.text.textchangerange?view=roslyn-dotnet-4.2.0\" rel=\"noopener noreferrer nofollow\">TextChangeRange<\/a>. \u042d\u0442\u043e \u0442\u0438\u043f \u0438\u0437 Roslyn. \u041e\u043d \u0433\u043e\u0432\u043e\u0440\u0438\u0442, \u043a\u0430\u043a\u043e\u0439 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0431\u044b\u043b \u0437\u0430\u043c\u0435\u043d\u0451\u043d \u0438 \u043a\u0430\u043a\u043e\u0439 \u0434\u043b\u0438\u043d\u044b \u0441\u0442\u0430\u043b \u043d\u043e\u0432\u044b\u0439 \u043a\u0443\u0441\u043e\u043a.<\/p>\n<p>\u0423\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u043e:<\/p>\n<pre><code class=\"cs\">var change = new TextChangeRange(    new TextSpan(start: 10, length: 5),    newLength: 8);<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442:<\/p>\n<pre><code>\u0432 \u0441\u0442\u0430\u0440\u043e\u043c \u0442\u0435\u043a\u0441\u0442\u0435 \u0441 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 10 \u0431\u044b\u043b\u043e 5 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432\u0432 \u043d\u043e\u0432\u043e\u043c \u0442\u0435\u043a\u0441\u0442\u0435 \u043d\u0430 \u044d\u0442\u043e\u043c \u043c\u0435\u0441\u0442\u0435 \u0442\u0435\u043f\u0435\u0440\u044c 8 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u0430\u0436\u043d\u043e, \u0447\u0442\u043e <code>TextChangeRange<\/code> \u0445\u0440\u0430\u043d\u0438\u0442 span \u0432 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u0445 \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430. \u0410 \u043f\u0430\u0440\u0441\u0435\u0440 \u0447\u0438\u0442\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u0442\u0435\u043a\u0441\u0442. \u0417\u043d\u0430\u0447\u0438\u0442 \u043d\u0430\u043c \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c old positions \u0438 new positions.<\/p>\n<p>\u041f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>old: state count = 0;new: state counter = 0;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041c\u044b \u0437\u0430\u043c\u0435\u043d\u0438\u043b\u0438 <code>count<\/code> \u043d\u0430 <code>counter<\/code>. \u0421\u0442\u0430\u0440\u044b\u0439 \u043a\u0443\u0441\u043e\u043a \u0434\u043b\u0438\u043d\u043e\u0439 5, \u043d\u043e\u0432\u044b\u0439 \u0434\u043b\u0438\u043d\u043e\u0439 7. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u0441\u0435 \u0441\u0442\u0430\u0440\u044b\u0435 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0441\u043f\u0440\u0430\u0432\u0430 \u043e\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u0434\u0432\u0438\u043d\u0443\u043b\u0438\u0441\u044c \u043d\u0430 <code>+2<\/code>.<\/p>\n<p>\u0412\u043e\u0442 \u044d\u0442\u043e \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0432 \u0431\u043b\u0435\u043d\u0434\u0435\u0440\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u043a\u0430\u043a <code>_changeDelta<\/code>.<\/p>\n<pre><code class=\"cs\">private readonly int _changeDelta;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u043e, \u0432\u0441\u0451 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u043e\u0441\u0442\u043e:<\/p>\n<pre><code class=\"cs\">newPosition = oldPosition + changeDelta<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e, \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u0441\u0432\u0435\u0440\u043d\u0443\u0442\u044c:<\/p>\n<pre><code class=\"cs\">var collapsed = TextChangeRange.Collapse(changes);<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e. \u0414\u0430 \u0438 \u043a \u0442\u043e\u043c\u0443 \u0436\u0435 \u0441\u0430\u043c\u0438 <code>Roslyn<\/code> \u0441\u0434\u0435\u043b\u0430\u043b\u0438 <a href=\"https:\/\/github.com\/dotnet\/roslyn\/blob\/eb789e2741f6f22d9e283e2049dc1378871323e0\/src\/Compilers\/CSharp\/Portable\/Parser\/Blender.cs#L56\" rel=\"noopener noreferrer nofollow\">\u0442\u0430\u043a \u0436\u0435<\/a>. \u042d\u0442\u043e \u043a\u0441\u0442\u0430\u0442\u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0443\u0434\u0438\u0432\u043b\u044f\u0435\u0442, \u0447\u0442\u043e \u043e\u043d\u0438 \u0434\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043b\u0438 \u044d\u0442\u0443 \u0442\u0443\u0434\u0443\u0448\u043a\u0443, \u0432\u0438\u0434\u0438\u043c\u043e \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0441\u043b\u043e\u0436\u043d\u043e \u0435\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c, \u043d\u0443 \u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430 \u0442\u0430\u043a \u043a\u0430\u043a \u0438\u0445 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0438 \u0442\u0430\u043a \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u044b\u0441\u0442\u0440.<\/p>\n<p>\u0412 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 <code>Blender<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u0442\u0430\u0440\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0438 \u043d\u0430\u0431\u043e\u0440 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439:<\/p>\n<pre><code class=\"cs\">public Blender(    Lexer lexer,    AkburaSyntax oldTree,    IEnumerable&lt;TextChangeRange&gt; changes){    _lexer = lexer;    _changes = ImmutableStack&lt;TextChangeRange&gt;.Empty;    if (changes != null)    {        var collapsed = TextChangeRange.Collapse(changes);        _changes = _changes.Push(ExtendToAffectedRange(oldTree, collapsed));    }    if (oldTree == null)    {        _oldTreeCursor = default;        _newPosition = lexer.TextWindow.Position;    }    else    {        _oldTreeCursor = new Cursor(oldTree).MoveToFirstChild();        _newPosition = 0;    }    _changeDelta = 0;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code>ExtendToAffectedRange<\/code> \u043f\u043e\u043a\u0430 \u043f\u043e\u0447\u0442\u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u0442. \u0412 Roslyn <a href=\"https:\/\/github.com\/dotnet\/roslyn\/blob\/eb789e2741f6f22d9e283e2049dc1378871323e0\/src\/Compilers\/CSharp\/Portable\/Parser\/Blender.cs#L111\" rel=\"noopener noreferrer nofollow\">ExtendToAffectedRange<\/a> \u0443\u0441\u0442\u0440\u043e\u0435\u043d \u0441\u043b\u043e\u0436\u043d\u0435\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e C# grammar \u0438\u043c\u0435\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u043c\u0435\u0441\u0442, \u0433\u0434\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u0441\u043c\u044b\u0441\u043b \u0441\u043e\u0441\u0435\u0434\u043d\u0435\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430 \u0438\u043b\u0438 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438. \u0412 Akbura \u043d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u044f \u043e\u0441\u0442\u0430\u0432\u0438\u043b \u043a\u043e\u043d\u0441\u0435\u0440\u0432\u0430\u0442\u0438\u0432\u043d\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c. \u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0441\u043e\u043c\u043d\u0435\u043d\u0438\u0435, \u043f\u0440\u043e\u0449\u0435 \u043d\u0435 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u0437\u0435\u043b. \u0413\u043b\u0430\u0432\u043d\u0430\u044f \u0446\u0435\u043b\u044c \u043f\u0435\u0440\u0432\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u2014 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u043e\u0442\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c.<\/p>\n<h2>BlendedNode<\/h2>\n<p>\u041f\u0430\u0440\u0441\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0443 \u0431\u043b\u0435\u043d\u0434\u0435\u0440\u0430 \u0434\u0432\u0435 \u0440\u0430\u0437\u043d\u044b\u0435 \u0432\u0435\u0449\u0438:<\/p>\n<ol>\n<li>\n<p>\u0434\u0430\u0439 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d<\/p>\n<\/li>\n<li>\n<p>\u0434\u0430\u0439 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 reusable node<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0443\u0436\u0435\u043d \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043c\u0435\u0435\u0442 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043b\u0438\u0431\u043e \u0441\u0442\u0430\u0440\u0443\u044e \u043a\u0440\u0430\u0441\u043d\u0443\u044e-\u043d\u043e\u0434\u0443, \u043b\u0438\u0431\u043e \u0442\u043e\u043a\u0435\u043d.<\/p>\n<p>\u0412 Akbura \u043e\u043d \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">internal readonly struct BlendedNode{    public readonly AkburaSyntax? Node;    public readonly SyntaxToken Token;    public readonly Blender Blender;    public BlendedNode(AkburaSyntax? node, SyntaxToken token, Blender blender)    {        Node = node;        Token = token;        Blender = blender;    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043d\u0435\u0442 \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438. \u042d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0447\u0442\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0415\u0441\u043b\u0438 <code>Node != null<\/code>, \u0431\u043b\u0435\u043d\u0434\u0435\u0440 \u0441\u043c\u043e\u0433 \u0432\u0437\u044f\u0442\u044c \u043a\u0443\u0441\u043e\u043a \u0438\u0437 \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0446\u0435\u043b\u044b\u0439 <code>GreenStateDeclarationSyntax<\/code> \u0438\u043b\u0438 <code>GreenMarkupRootSyntax<\/code>.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0440\u0438\u0448\u0451\u043b <code>Token<\/code>, \u0437\u043d\u0430\u0447\u0438\u0442 \u0441\u0442\u0430\u0440\u044b\u0439 \u0443\u0437\u0435\u043b \u043d\u0435 \u043f\u043e\u0434\u043e\u0448\u0451\u043b, \u0438 \u0431\u043b\u0435\u043d\u0434\u0435\u0440 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043b \u043d\u043e\u0432\u044b\u0439 \u0442\u043e\u043a\u0435\u043d \u0438\u0437 \u043b\u0435\u043a\u0441\u0435\u0440\u0430.<\/p>\n<p>\u0422\u0440\u0435\u0442\u044c\u0435 \u043f\u043e\u043b\u0435 \u2014 <code>Blender<\/code>. \u042d\u0442\u043e \u0432\u0430\u0436\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c.<\/p>\n<p><code>Blender<\/code> \u0441\u0434\u0435\u043b\u0430\u043d \u0438\u043c\u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u043c. \u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u0447\u0438\u0442\u0430\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442, \u0441\u0442\u0430\u0440\u044b\u0439 \u0431\u043b\u0435\u043d\u0434\u0435\u0440 \u043d\u0435 \u043c\u0443\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u0430\u0440\u0443\u0436\u0443. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u0431\u043b\u0435\u043d\u0434\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0436\u0435 \u0437\u043d\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 cursor \u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 change state.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0447\u0442\u0435\u043d\u0438\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">var first = blender.ReadToken(Lexer.LexerMode.TopLevel);var second = first.Blender.ReadToken(Lexer.LexerMode.TopLevel);<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432. \u041c\u043e\u0436\u043d\u043e \u044f\u0432\u043d\u043e \u0432\u0438\u0434\u0435\u0442\u044c, \u0447\u0442\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0448\u0430\u0433 \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0435\u0440\u043d\u0443\u043b \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u0448\u0430\u0433.<\/p>\n<h2>Cursor<\/h2>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e, \u0435\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u043a\u0430\u043a-\u0442\u043e \u043e\u0431\u0445\u043e\u0434\u0438\u0442\u044c. \u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0438\u0441\u043a\u0430\u0442\u044c \u0443\u0437\u0435\u043b \u043f\u043e \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0447\u0435\u0440\u0435\u0437 tree APIs, \u043d\u043e \u044d\u0442\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u0441\u0442\u0430\u043d\u0435\u0442 \u0434\u043e\u0440\u043e\u0433\u043e. \u0411\u043b\u0435\u043d\u0434\u0435\u0440 \u0447\u0438\u0442\u0430\u0435\u0442 \u043f\u043e\u0442\u043e\u043a \u0441\u043b\u0435\u0432\u0430 \u043d\u0430\u043f\u0440\u0430\u0432\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438 \u0441\u0442\u0430\u0440\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0443\u0434\u043e\u0431\u043d\u043e \u043e\u0431\u0445\u043e\u0434\u0438\u0442\u044c \u0441\u043b\u0435\u0432\u0430 \u043d\u0430\u043f\u0440\u0430\u0432\u043e.<\/p>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0435\u0441\u0442\u044c <code>Blender.Cursor<\/code>.<\/p>\n<pre><code class=\"cs\">internal readonly struct Cursor{    private readonly SyntaxNodeOrToken _current;    private readonly PathNode? _parent;    private readonly int _indexInParent;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>Cursor \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 root:<\/p>\n<pre><code class=\"cs\">public Cursor(AkburaSyntax root)    : this(new SyntaxNodeOrToken(root), parent: null, indexInParent: 0){}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u043e \u0441\u0430\u043c root \u043d\u0430\u043c \u043e\u0431\u044b\u0447\u043d\u043e \u043d\u0435 \u043d\u0443\u0436\u0435\u043d. \u041f\u0430\u0440\u0441\u0435\u0440 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u044c <code>AkburaDocumentSyntax<\/code> \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0431\u043b\u0435\u043d\u0434\u0435\u0440\u0430, \u043a\u0443\u0440\u0441\u043e\u0440 \u0441\u0440\u0430\u0437\u0443 \u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u043a \u043f\u0435\u0440\u0432\u043e\u043c\u0443 child:<\/p>\n<pre><code class=\"cs\">_oldTreeCursor = new Cursor(oldTree).MoveToFirstChild();<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>MoveToFirstChild<\/h3>\n<p><code>MoveToFirstChild<\/code> \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0441\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u044c \u0442\u0435\u043a\u0443\u0449\u0435\u0439 node:<\/p>\n<pre><code class=\"cs\">public Cursor MoveToFirstChild(){    if (IsFinished || !_current.AsNode(out var node))    {        return MoveToNextSibling();    }    var children = node.ChildNodesAndTokens();    if (TryGetFirstNonZeroWidthChild(children, out var child, out var childIndex))    {        return new Cursor(            child,            new PathNode(_current, _parent, _indexInParent, children),            childIndex);    }    return MoveToNextSibling();}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u0435\u0442\u0430\u043b\u0435\u0439.<\/p>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, cursor \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 red tree, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0443\u0434\u043e\u0431\u043d\u0435\u0435 \u0431\u0440\u0430\u0442\u044c \u0438\u043c\u0435\u043d\u043d\u043e \u043e\u0442 red nodes \u0438 \u0442\u043e\u043a\u0435\u043d\u043e\u0432. Green tree \u0445\u0440\u0430\u043d\u0438\u0442 \u0448\u0438\u0440\u0438\u043d\u0443, \u043d\u043e \u043d\u0435 \u0445\u0440\u0430\u043d\u0438\u0442 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0432 \u0444\u0430\u0439\u043b\u0435. \u0410 \u0431\u043b\u0435\u043d\u0434\u0435\u0440 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442 \u0441\u0442\u0430\u0440\u044b\u0435 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0441 \u043d\u043e\u0432\u044b\u043c\u0438.<\/p>\n<p>\u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, cursor \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442 zero-width children. \u0412 syntax tree \u0447\u0430\u0441\u0442\u043e \u0431\u044b\u0432\u0430\u044e\u0442 missing-\u0442\u043e\u043a\u0435\u043d\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0430\u0440\u0441\u0435\u0440 \u043e\u0436\u0438\u0434\u0430\u043b <code>;<\/code>, \u043d\u0435 \u043d\u0430\u0448\u0451\u043b \u0435\u0433\u043e \u0438 \u0441\u043e\u0437\u0434\u0430\u043b missing semicolon-\u0442\u043e\u043a\u0435\u043d \u0448\u0438\u0440\u0438\u043d\u043e\u0439 <code>0<\/code>. \u0414\u043b\u044f \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430 \u044d\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e: \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u043e\u0439. \u0414\u043b\u044f \u043f\u043e\u0442\u043e\u043a\u0430 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0430\u043a\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u043c\u0435\u0448\u0430\u0442\u044c. \u041e\u043d\u0438 \u043d\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0442 \u043c\u0435\u0441\u0442\u0430 \u0432 \u0442\u0435\u043a\u0441\u0442\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 cursor \u0438\u0445 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442.<\/p>\n<p>\u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435  <code>EndOfFileToken<\/code>:<\/p>\n<pre><code class=\"cs\">private static bool IsNonZeroWidthOrIsEndOfFile(SyntaxNodeOrToken nodeOrToken){    var underlying = nodeOrToken.UnderlyingNode;    return underlying != null &amp;&amp;           (underlying.FullWidth &gt; 0 ||            underlying.Kind == SyntaxKind.EndOfFileToken);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>EOF \u0442\u043e\u0436\u0435 zero-width, \u043d\u043e \u044d\u0442\u043e \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u0442\u043e\u043a\u0435\u043d \u043a\u043e\u043d\u0446\u0430 \u043f\u043e\u0442\u043e\u043a\u0430.<\/p>\n<h3>MoveToNextSibling<\/h3>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0443\u0437\u0435\u043b \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d, \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0441\u043e\u0441\u0435\u0434\u0443:<\/p>\n<pre><code class=\"cs\">public Cursor MoveToNextSibling(){    if (IsFinished)    {        return default;    }    var parent = _parent;    if (parent == null)    {        return default;    }    if (TryGetNextNonZeroWidthChild(            parent.Children,            _indexInParent + 1,            out var sibling,            out var siblingIndex))    {        return new Cursor(sibling, parent, siblingIndex);    }    return MoveToParent().MoveToNextSibling();}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 sibling \u0435\u0441\u0442\u044c, \u0432\u0441\u0451 \u043f\u0440\u043e\u0441\u0442\u043e. \u0415\u0441\u043b\u0438 sibling-\u0430 \u043d\u0435\u0442, cursor \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043a \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044e \u0438 \u0438\u0449\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0441\u043e\u0441\u0435\u0434\u0430 \u0443\u0436\u0435 \u0443 \u043d\u0435\u0433\u043e.<\/p>\n<p>\u0418\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u044d\u0442\u043e\u043c\u0443 cursor \u0445\u0440\u0430\u043d\u0438\u0442 <code>PathNode<\/code>:<\/p>\n<pre><code class=\"cs\">private sealed class PathNode{    public readonly SyntaxNodeOrToken NodeOrToken;    public readonly PathNode? Parent;    public readonly int IndexInParent;    public readonly ChildSyntaxList Children;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u0441\u0442\u0435\u043a \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u0435\u0439. \u041e\u043d \u043d\u0443\u0436\u0435\u043d, \u0447\u0442\u043e\u0431\u044b \u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f \u043f\u043e \u0434\u0435\u0440\u0435\u0432\u0443 \u0431\u0435\u0437 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e\u0433\u043e \u043e\u0431\u0445\u043e\u0434\u0447\u0438\u043a\u0430 \u0438 \u0431\u0435\u0437 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438 \u043e\u0442 root.<\/p>\n<h3>MoveToParent<\/h3>\n<p>\u0418\u043d\u043e\u0433\u0434\u0430 \u0431\u043b\u0435\u043d\u0434\u0435\u0440 \u0441\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0433\u043b\u0443\u0431\u043e\u043a\u043e \u0438 \u043f\u043e\u0442\u043e\u043c \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u0434\u043d\u044f\u0442\u044c\u0441\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u0433\u0434\u0430 \u043e\u043d \u0438\u0441\u043a\u0430\u043b \u043f\u0435\u0440\u0432\u044b\u0439 \u0442\u043e\u043a\u0435\u043d \u0432\u043d\u0443\u0442\u0440\u0438 node \u0438\u043b\u0438 \u043a\u043e\u0433\u0434\u0430 <code>MoveToReusableNode<\/code> \u0445\u043e\u0447\u0435\u0442 \u043d\u0430\u0439\u0442\u0438 \u0441\u0430\u043c\u044b\u0439 \u043a\u0440\u0443\u043f\u043d\u044b\u0439 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439 \u0443\u0437\u0435\u043b.<\/p>\n<pre><code class=\"cs\">public Cursor MoveToParent(){    if (IsFinished)    {        return default;    }    var parent = _parent;    if (parent == null)    {        return default;    }    return new Cursor(parent.NodeOrToken, parent.Parent, parent.IndexInParent);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u0430\u043c\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0441\u0442\u0430\u044f, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u0443\u0442\u044c \u0443\u0436\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d.<\/p>\n<h2>Reader<\/h2>\n<p><code>Cursor<\/code> \u0442\u043e\u043b\u044c\u043a\u043e \u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u0441\u0442\u0430\u0440\u043e\u043c\u0443 \u0434\u0435\u0440\u0435\u0432\u0443. \u0420\u0435\u0448\u0435\u043d\u0438\u0435, \u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0438\u043b\u0438 \u043d\u043e\u0432\u044b\u0439 \u043b\u0435\u043a\u0441\u0435\u0440, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 <code>Blender.Reader<\/code>.<\/p>\n<p>\u0412\u043d\u0435\u0448\u043d\u0438\u0439 <code>Blender<\/code> \u043f\u043e\u0447\u0442\u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 \u0441\u0430\u043c:<\/p>\n<pre><code class=\"cs\">public BlendedNode ReadNode(Lexer.LexerMode mode){    return ReadNodeOrToken(mode, asToken: false);}public BlendedNode ReadToken(Lexer.LexerMode mode){    return ReadNodeOrToken(mode, asToken: true);}public BlendedNode ReadFreshToken(Lexer.LexerMode mode){    var reader = new Reader(this);    return reader.ReadFreshToken(mode);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u043d \u0441\u043e\u0437\u0434\u0430\u0451\u0442 <code>Reader<\/code>, <code>reader<\/code> \u0434\u0435\u043b\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 <code>Blender<\/code> \u0432\u043d\u0443\u0442\u0440\u0438 <code>BlendedNode<\/code>.<\/p>\n<p>\u0423 <code>reader<\/code>-\u0430 \u0435\u0441\u0442\u044c mutable \u043f\u043e\u043b\u044f:<\/p>\n<pre><code class=\"cs\">private struct Reader{    private Lexer _lexer;    private Cursor _oldTreeCursor;    private ImmutableStack&lt;TextChangeRange&gt; _changes;    private int _newPosition;    private int _changeDelta;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0447\u0442\u0435\u043d\u0438\u044f \u0443\u0434\u043e\u0431\u043d\u043e \u043c\u0443\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435. \u041d\u0430\u0440\u0443\u0436\u0443 \u044d\u0442\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u043d\u043e\u0432\u044b\u0439 <code>Blender<\/code>:<\/p>\n<pre><code class=\"cs\">private Blender CreateBlender(){    return new Blender(        _lexer,        _oldTreeCursor,        _changes,        _newPosition,        _changeDelta);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>ReadNodeOrToken<\/h3>\n<p>\u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 <code>reader<\/code>-\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">public BlendedNode ReadNodeOrToken(Lexer.LexerMode mode, bool asToken){    SkipPastChanges();    if (!IsWithinCurrentChangeInNewText(_newPosition))    {        SkipOldTreePastNewPosition();    }    if (TryReadOldNodeOrToken(mode, asToken, out var blended))    {        return blended;    }    if (!asToken)    {        return default;    }    _oldTreeCursor = MoveToFirstToken(_oldTreeCursor);    return ReadNewToken(mode);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0440\u044f\u0434\u043e\u043a \u0442\u0430\u043a\u043e\u0439:<\/p>\n<ol>\n<li>\n<p>\u0443\u0431\u0440\u0430\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u0436\u0435 \u043e\u0441\u0442\u0430\u043b\u0438\u0441\u044c \u043f\u043e\u0437\u0430\u0434\u0438<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044c old cursor \u0434\u043e \u0442\u0435\u043a\u0443\u0449\u0435\u0439 new position<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0432\u0437\u044f\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0439 node \u0438\u043b\u0438 \u0442\u043e\u043a\u0435\u043d<\/p>\n<\/li>\n<li>\n<p>\u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u0435\u043d \u0442\u043e\u043a\u0435\u043d \u0438 \u0441\u0442\u0430\u0440\u044b\u0439 \u0442\u043e\u043a\u0435\u043d \u043d\u0435 \u043f\u043e\u0434\u043e\u0448\u0451\u043b, \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0432\u0435\u0436\u0438\u0439 \u0442\u043e\u043a\u0435\u043d \u0438\u0437 \u043b\u0435\u043a\u0441\u0435\u0440\u0430<\/p>\n<\/li>\n<\/ol>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0430\u0440\u0441\u0435\u0440 \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u043b node, \u0430 \u0441\u0442\u0430\u0440\u044b\u0439 node \u043d\u0435 \u043f\u043e\u0434\u043e\u0448\u0451\u043b, <code>reader<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>default<\/code>. \u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442: reusable node \u0441\u0435\u0439\u0447\u0430\u0441 \u043d\u0435\u0442, \u043f\u0430\u0440\u0441\u0435\u0440 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u0439\u0442\u0438 \u043e\u0431\u044b\u0447\u043d\u044b\u043c \u043f\u0443\u0442\u0451\u043c \u0438 \u0447\u0438\u0442\u0430\u0442\u044c \u0442\u043e\u043a\u0435\u043d\u044b.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0430\u0440\u0441\u0435\u0440 \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u043b \u0442\u043e\u043a\u0435\u043d, \u043e\u043d \u0432\u0441\u0435\u0433\u0434\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u043e\u043a\u0435\u043d. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 fallback \u0438\u0434\u0451\u0442 \u0432 \u043b\u0435\u043a\u0441\u0435\u0440.<\/p>\n<h3>SkipPastChanges<\/h3>\n<p>\u041a\u043e\u0433\u0434\u0430 <code>_newPosition<\/code> \u0443\u0436\u0435 \u0443\u0448\u043b\u0430 \u043f\u0440\u0430\u0432\u0435\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, change \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043a\u0438\u043d\u0443\u0442\u044c \u0438\u0437 \u0441\u0442\u0435\u043a\u0430:<\/p>\n<pre><code class=\"cs\">private void SkipPastChanges(){    while (!_changes.IsEmpty)    {        var change = _changes.Peek();        var newEnd = change.Span.Start + _changeDelta + change.NewLength;        if (_newPosition &lt; newEnd)        {            break;        }        _changes = _changes.Pop();        _changeDelta += change.NewLength - change.Span.Length;    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418\u043c\u0435\u043d\u043d\u043e \u0437\u0434\u0435\u0441\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>_changeDelta<\/code>.<\/p>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0441\u0442\u0430\u0440\u044b\u0439 \u043a\u0443\u0441\u043e\u043a \u0431\u044b\u043b \u0434\u043b\u0438\u043d\u043e\u0439 <code>5<\/code>, \u043d\u043e\u0432\u044b\u0439 \u0441\u0442\u0430\u043b \u0434\u043b\u0438\u043d\u043e\u0439 <code>7<\/code>. \u041f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f delta \u0441\u0442\u0430\u043d\u0435\u0442 <code>+2<\/code>. \u0412\u0441\u0435 \u0441\u0442\u0430\u0440\u044b\u0435 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u043f\u0440\u0430\u0432\u0435\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u043f\u0435\u0440\u044c \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441 \u043d\u043e\u0432\u044b\u043c\u0438 \u043f\u043e\u0437\u0438\u0446\u0438\u044f\u043c\u0438 \u0441 \u044d\u0442\u0438\u043c \u0441\u0434\u0432\u0438\u0433\u043e\u043c.<\/p>\n<h3>IsWithinCurrentChangeInNewText<\/h3>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0438\u0437\u043c\u0435\u043d\u0451\u043d\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u0445 \u043d\u043e\u0432\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430:<\/p>\n<pre><code class=\"cs\">private bool IsWithinCurrentChangeInNewText(int position){    if (_changes.IsEmpty)    {        return false;    }    var change = _changes.Peek();    var newStart = change.Span.Start + _changeDelta;    var newEnd = change.Span.Start + _changeDelta + change.NewLength;    return position &gt;= newStart &amp;&amp; position &lt; newEnd;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u044f \u0432\u043d\u0443\u0442\u0440\u0438 changed range, \u0441\u0442\u0430\u0440\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u043b\u044c\u0437\u044f. \u0414\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0442\u0430\u043c \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e \u043b\u0435\u0436\u0438\u0442 \u043f\u043e\u0445\u043e\u0436\u0438\u0439 \u0442\u043e\u043a\u0435\u043d, \u0435\u0433\u043e \u043d\u0435\u043b\u044c\u0437\u044f \u0431\u0440\u0430\u0442\u044c: \u0442\u0435\u043a\u0441\u0442 \u043f\u043e\u043c\u0435\u043d\u044f\u043b\u0441\u044f.<\/p>\n<h3>TryReadOldNodeOrToken<\/h3>\n<p>\u042d\u0442\u043e \u0441\u0435\u0440\u0434\u0446\u0435 \u0431\u043b\u0435\u043d\u0434\u0435\u0440\u0430:<\/p>\n<pre><code class=\"cs\">private bool TryReadOldNodeOrToken(    Lexer.LexerMode mode,    bool asToken,    out BlendedNode blended){    if (IsWithinCurrentChangeInNewText(_newPosition))    {        blended = default;        return false;    }    var cursor = asToken        ? MoveToFirstToken(_oldTreeCursor)        : MoveToReusableNode(_oldTreeCursor);    if (cursor.IsFinished)    {        blended = default;        return false;    }    var nodeOrToken = cursor.Current;    var oldSpan = nodeOrToken.FullSpan;    var expectedNewPosition = oldSpan.Start + _changeDelta;    if (expectedNewPosition != _newPosition ||        IntersectsNextChange(oldSpan) ||        !CanReuse(nodeOrToken, asToken))    {        blended = default;        return false;    }    _newPosition += nodeOrToken.FullSpan.Length;    _oldTreeCursor = cursor;    _oldTreeCursor = MoveOldTreePast(_newPosition);    _lexer.TextWindow.Reset(_newPosition);    blended = asToken        ? new BlendedNode(null, nodeOrToken.AsToken(), CreateBlender())        : new BlendedNode(nodeOrToken.AsNode(), default, CreateBlender());    return true;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 <code>reader<\/code> \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442, \u0447\u0442\u043e \u0438\u0441\u043a\u0430\u0442\u044c:<\/p>\n<pre><code class=\"cs\">asToken == true   =&gt; \u0441\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u0441\u044f \u0434\u043e \u043f\u0435\u0440\u0432\u043e\u0433\u043e tokenasToken == false  =&gt; \u043d\u0430\u0439\u0442\u0438 reusable node<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0442\u043e\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043f\u043e\u0437\u0438\u0446\u0438\u044e.<\/p>\n<pre><code class=\"cs\">var expectedNewPosition = oldSpan.Start + _changeDelta;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0441\u0442\u0430\u0440\u044b\u0439 \u0443\u0437\u0435\u043b \u043f\u043e\u0441\u043b\u0435 \u0443\u0447\u0451\u0442\u0430 delta \u0434\u043e\u043b\u0436\u0435\u043d \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0442\u0430\u043c, \u0433\u0434\u0435 \u0441\u0435\u0439\u0447\u0430\u0441 \u0441\u0442\u043e\u0438\u0442 <code>reader<\/code>, \u0437\u043d\u0430\u0447\u0438\u0442 \u043e\u043d \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442. \u0422\u0430\u043a\u043e\u0435 \u0431\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u0441\u043b\u0435 \u0432\u0441\u0442\u0430\u0432\u043a\u0438\/\u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435, \u043a\u043e\u0433\u0434\u0430 cursor \u0435\u0449\u0451 \u043d\u0435 \u0434\u043e\u0433\u043d\u0430\u043b \u043d\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c change:<\/p>\n<pre><code class=\"cs\">IntersectsNextChange(oldSpan)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0441\u0442\u0430\u0440\u044b\u0439 \u0443\u0437\u0435\u043b \u0445\u043e\u0442\u044f \u0431\u044b \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u0441 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435\u043c, \u0435\u0433\u043e \u043d\u0435\u043b\u044c\u0437\u044f \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0446\u0435\u043b\u0438\u043a\u043e\u043c. \u041d\u0443\u0436\u043d\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u0437\u0430\u043d\u043e\u0432\u043e \u0445\u043e\u0442\u044f \u0431\u044b \u044d\u0442\u0443 \u043e\u0431\u043b\u0430\u0441\u0442\u044c.<\/p>\n<p>\u0418 \u043d\u0430\u043a\u043e\u043d\u0435\u0446 <code>CanReuse<\/code>.<\/p>\n<h3>ReadNewToken<\/h3>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0441\u0442\u0430\u0440\u044b\u0439 node \u0438\u043b\u0438 \u0442\u043e\u043a\u0435\u043d \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442, <code>reader<\/code> \u0438\u0434\u0451\u0442 \u0432 \u043b\u0435\u043a\u0441\u0435\u0440:<\/p>\n<pre><code class=\"cs\">private BlendedNode ReadNewToken(Lexer.LexerMode mode){    _lexer.TextWindow.Reset(_newPosition);    var position = _lexer.TextWindow.Position;    var token = _lexer.Lex(mode);    var nextCursor = IsWithinCurrentChangeInNewText(position)        ? _oldTreeCursor        : MoveOldTreePast(position + token.FullWidth);    _oldTreeCursor = nextCursor;    _newPosition += token.FullWidth;    return new BlendedNode(        null,        new SyntaxToken(parent: null, token: token, position: position, index: 0),        CreateBlender());}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0443\u0442 \u0432\u0438\u0434\u043d\u043e, \u043f\u043e\u0447\u0435\u043c\u0443 <code>FullWidth<\/code> \u0442\u0430\u043a \u0432\u0430\u0436\u0435\u043d. \u0415\u0441\u043b\u0438 \u0442\u043e\u043a\u0435\u043d \u0438\u043b\u0438 node \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0435\u0442 \u0448\u0438\u0440\u0438\u043d\u0443, \u0431\u043b\u0435\u043d\u0434\u0435\u0440 \u043d\u0430\u0447\u043d\u0451\u0442 \u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0442\u0443\u0434\u0430. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043a\u0430\u043a \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u0441\u0434\u0432\u0438\u0433 \u043d\u0430 \u043e\u0434\u0438\u043d \u043f\u0440\u043e\u0431\u0435\u043b, \u0430 \u043f\u043e\u0442\u043e\u043c \u043f\u0430\u0440\u0441\u0435\u0440 \u0432\u043d\u0435\u0437\u0430\u043f\u043d\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0432\u0438\u0434\u0435\u0442\u044c <code>state int after  1;;<\/code> \u0438\u043b\u0438 \u043f\u043e\u0445\u043e\u0436\u0438\u0435 \u0447\u0443\u0434\u0435\u0441\u0430.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0437\u0436\u0435 \u0432 \u0442\u0435\u0441\u0442\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0430\u0441\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430:<\/p>\n<pre><code class=\"cs\">Assert.Equal(code.Length, syntax.FullWidth);<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code>ToFullString()<\/code> \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0442\u0435\u043a\u0441\u0442. <code>FullWidth<\/code> \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044e\u044e \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0443 \u0434\u0435\u0440\u0435\u0432\u0430. \u0418 \u043a\u0430\u043a \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u043e\u043a\u043e\u043b\u043e 8 \u043d\u043e\u0434 \u0443 \u043c\u0435\u043d\u044f \u043d\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0447\u0438\u0442\u0430\u043b\u0438 \u0448\u0438\u0440\u0438\u043d\u0443, \u044d\u0442\u043e \u043d\u0435 \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439 \u0440\u0430\u043d\u044c\u0448\u0435, \u043d\u043e \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c \u0434\u043e \u0431\u043b\u0435\u043d\u0434\u0435\u0440\u0430 \u201c\u0441\u043f\u044f\u0449\u0438\u0435\u201d \u0431\u0430\u0433\u0438 \u043f\u0440\u043e\u0431\u0443\u0434\u0438\u043b\u0438\u0441\u044c.<\/p>\n<h2>\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435<\/h2>\n<p>\u041f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430 \u2014 \u044d\u0442\u043e \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f. \u042d\u0442\u043e \u0435\u0449\u0451 \u0438 \u0440\u0438\u0441\u043a. \u0415\u0441\u043b\u0438 \u0432\u0437\u044f\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0439 \u0443\u0437\u0435\u043b \u0442\u0430\u043c, \u0433\u0434\u0435 \u0442\u0435\u043a\u0441\u0442 \u0443\u0436\u0435 \u043f\u043e\u043c\u0435\u043d\u044f\u043b\u0441\u044f \u0438\u043b\u0438 \u0433\u0434\u0435 \u0441\u0442\u0430\u0440\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0431\u044b\u043b\u043e \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u044b\u043c, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0435\u0440\u0435\u0432\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043d\u043e\u0432\u043e\u043c\u0443 \u0442\u0435\u043a\u0441\u0442\u0443.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043b\u0443\u0447\u0448\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u0433\u0438\u043c\u0438.<\/p>\n<p>\u0412 Akbura \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">private static bool CanReuse(SyntaxNodeOrToken nodeOrToken, bool asToken){    if (ContainsDiagnosticsOrSkippedText(nodeOrToken.RequiredUnderlyingNode))    {        return false;    }    return asToken        ? nodeOrToken.IsToken        : nodeOrToken.IsNode;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u0430\u043c\u043e\u0435 \u0432\u0430\u0436\u043d\u043e\u0435:<\/p>\n<ol>\n<li>\n<p>\u0443\u0437\u043b\u044b \u0441 diagnostics \u043d\u0435 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c<\/p>\n<\/li>\n<li>\n<p>\u0443\u0437\u043b\u044b \u0441\u043e skipped text \u043d\u0435 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c<\/p>\n<\/li>\n<li>\n<p>\u0438\u0437\u043c\u0435\u043d\u0451\u043d\u043d\u044b\u0439 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u043d\u0435 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c<\/p>\n<\/li>\n<li>\n<p>\u0442\u0438\u043f \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u043d\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c: \u0442\u043e\u043a\u0435\u043d \u0438\u043b\u0438 node<\/p>\n<\/li>\n<\/ol>\n<h3>Diagnostics \u0438 skipped text<\/h3>\n<p>\u0415\u0441\u043b\u0438 \u0441\u0442\u0430\u0440\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0447\u0442\u043e-\u0442\u043e \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b \u0447\u0435\u0440\u0435\u0437 diagnostics, \u0442\u0430\u043a\u043e\u0439 \u0443\u0437\u0435\u043b \u043b\u0443\u0447\u0448\u0435 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u0437\u0430\u043d\u043e\u0432\u043e. \u0412 IDE \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0447\u0430\u0441\u0442\u043e \u043f\u0435\u0447\u0430\u0442\u0430\u0435\u0442 \u043a\u043e\u0434 \u0432 \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438. \u0415\u0441\u043b\u0438 \u043c\u044b \u043d\u0430\u0447\u043d\u0451\u043c \u0430\u0433\u0440\u0435\u0441\u0441\u0438\u0432\u043d\u043e \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u043e\u043c\u0430\u043d\u043d\u044b\u0435 \u043a\u0443\u0441\u043a\u0438, \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443 \u0438 \u043d\u0435 \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u0447\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0435\u0451 \u0443\u0436\u0435 \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u043b.<\/p>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">private static bool ContainsDiagnosticsOrSkippedText(GreenNode node){    if (node.Kind == SyntaxKind.InlineExpressionSyntax)    {        return ContainsInvalidInlineExpression(Unsafe.As&lt;GreenInlineExpressionSyntax&gt;(node));    }    if (node.Kind is SyntaxKind.CSharpExpressionSyntax or        SyntaxKind.CSharpTypeSyntax or        SyntaxKind.CSharpParameterListSyntax or        SyntaxKind.CSharpArgumentListSyntax)    {        return false;    }    if (node.ContainsSkippedText)    {        return true;    }    if (!node.ContainsDiagnostics)    {        return false;    }    return ContainsDiagnosticsOrSkippedTextSlow(node);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0435\u0441\u0442\u044c \u0432\u0430\u0436\u043d\u043e\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f C# raw nodes. Akbura \u0445\u0440\u0430\u043d\u0438\u0442 C# fragments \u043a\u0430\u043a <code>CSharpRawToken<\/code> \/ <code>CSharpExpressionSyntax<\/code> \/ <code>CSharpTypeSyntax<\/code>. \u0412\u043d\u0443\u0442\u0440\u0438 \u043d\u0438\u0445 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c Roslyn diagnostics, \u043d\u043e \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 Akbura \u044d\u0442\u043e \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u043f\u0440\u0435\u0442\u0438\u0442\u044c reuse. \u0421\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 C# \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0438\u0441\u0442\u043e\u0440\u0438\u0435\u0439.<\/p>\n<h3>\u0420\u0435\u0436\u0438\u043c \u043b\u0435\u043a\u0441\u0435\u0440\u0430<\/h3>\n<p>\u0415\u0449\u0451 \u043e\u0434\u0438\u043d \u0438\u043d\u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u2014 \u0440\u0435\u0436\u0438\u043c \u043b\u0435\u043a\u0441\u0435\u0440\u0430.<\/p>\n<p>Akbura-\u043f\u0430\u0440\u0441\u0435\u0440 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u043b\u0435\u043a\u0441\u0435\u0440:<\/p>\n<pre><code>1. TopLevel2. InAkcss3. InInlineExpression4. InExpressionUntilSemicolon5. InTypeName6. InCSharpParameterList...<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u0442\u0435\u043a\u0441\u0442 \u043c\u043e\u0436\u0435\u0442 \u0447\u0438\u0442\u0430\u0442\u044c\u0441\u044f \u043f\u043e-\u0440\u0430\u0437\u043d\u043e\u043c\u0443 \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u0440\u0435\u0436\u0438\u043c\u0430\u0445. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043d\u0443\u0442\u0440\u0438 C# expression \u043b\u0435\u043a\u0441\u0435\u0440 \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0447\u0438\u0442\u0430\u0442\u044c Akbura markup \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u044b\u0439 top-level member. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u043b\u0435\u043d\u0434\u0435\u0440 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 <code>Lexer.LexerMode mode<\/code> \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u0447\u0442\u0435\u043d\u0438\u0438:<\/p>\n<pre><code class=\"cs\">public BlendedNode ReadToken(Lexer.LexerMode mode)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e fallback-\u043d\u0443\u0442\u044c\u0441\u044f \u043d\u0430 \u0441\u0432\u0435\u0436\u0438\u0439 \u0442\u043e\u043a\u0435\u043d, <code>reader<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043b\u0435\u043a\u0441\u0435\u0440 \u0438\u043c\u0435\u043d\u043d\u043e \u0432 \u044d\u0442\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435:<\/p>\n<pre><code class=\"cs\">var token = _lexer.Lex(mode);<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h2>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0431\u043b\u0435\u043d\u0434\u0435\u0440 \u043a \u043f\u0430\u0440\u0441\u0435\u0440\u0443<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u0432\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0431\u043b\u0435\u043d\u0434\u0435\u0440 \u0432 \u043f\u0430\u0440\u0441\u0435\u0440. \u0412 \u043e\u0431\u044b\u0447\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u043f\u0430\u0440\u0441\u0435\u0440 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u0440\u0430\u043d\u044c\u0448\u0435. \u0412 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u043e\u043d \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0441\u0442\u0430\u0440\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0438 changes.<\/p>\n<p>\u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">public Parser(    Lexer lexer,    CancellationToken cancellationToken,    AkburaDocumentSyntax? oldTree,    IEnumerable&lt;TextChangeRange&gt;? changes)    : this(lexer, cancellationToken){    if (oldTree == null)    {        return;    }    _isIncremental = true;    _blender = new Blender(lexer, oldTree, changes);    _blendersBeforeToken = s_blendersBeforeTokenPool.Allocate();}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 <code>oldTree == null<\/code>, \u043f\u0430\u0440\u0441\u0435\u0440 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043e\u0431\u044b\u0447\u043d\u044b\u043c.<\/p>\n<p>\u0412 \u043e\u0431\u044b\u0447\u043d\u043e\u043c \u043f\u0430\u0440\u0441\u0435\u0440\u0435 \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d \u0442\u043e\u043a\u0435\u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u043e\u0439:<\/p>\n<pre><code class=\"cs\">CurrentToken \/ PeekToken =&gt; cached token array =&gt; lexer.Lex(mode)EatToken                =&gt; consume current tokenReturnToken             =&gt; \u043e\u0442\u043a\u0430\u0442\u0438\u0442\u044c token offset \u0438 TextWindow<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f. \u041d\u043e\u0432\u044b\u0439 \u0442\u043e\u043a\u0435\u043d \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0447\u0435\u0440\u0435\u0437 \u0431\u043b\u0435\u043d\u0434\u0435\u0440:<\/p>\n<pre><code class=\"cs\">private void AddNewBlendedToken(){    var beforeToken = _blender;    var blended = _blender.ReadFreshToken(_mode);    _blender = blended.Blender;    AddLexedToken((GreenSyntaxToken)blended.Token.RequiredNode);    _blendersBeforeToken![_tokenCount - 1] = beforeToken;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0431\u043b\u0435\u043d\u0434\u0435\u0440 \u043f\u0435\u0440\u0435\u0434 \u0447\u0442\u0435\u043d\u0438\u0435\u043c \u0442\u043e\u043a\u0435\u043d\u0430. \u042d\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f <code>ReturnToken<\/code>.<\/p>\n<h3>ReturnToken<\/h3>\n<p>\u041f\u0430\u0440\u0441\u0435\u0440 \u0438\u043d\u043e\u0433\u0434\u0430 \u0437\u0430\u0433\u043b\u044f\u0434\u044b\u0432\u0430\u0435\u0442 \u0432\u043f\u0435\u0440\u0451\u0434, \u043f\u043e\u0442\u043e\u043c \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u043e\u0448\u0451\u043b \u043d\u0435 \u0442\u0443\u0434\u0430, \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0442\u043e\u043a\u0435\u043d \u043d\u0430\u0437\u0430\u0434. \u0412 \u043e\u0431\u044b\u0447\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043a\u0430\u0442\u0438\u0442\u044c <code>TextWindow<\/code>. \u0412 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043a\u0430\u0442\u0438\u0442\u044c \u0435\u0449\u0451 \u0438 \u0431\u043b\u0435\u043d\u0434\u0435\u0440 \u0441\u0442\u0435\u0439\u0442.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0435\u0440\u0435\u0434 \u043a\u0430\u0436\u0434\u044b\u043c \u0442\u043e\u043a\u0435\u043d\u043e\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0431\u043b\u0435\u043d\u0434\u0435\u0440:<\/p>\n<pre><code class=\"cs\">private static readonly ObjectPool&lt;Blender[]&gt; s_blendersBeforeTokenPool =    new(() =&gt; new Blender[CachedTokenArraySize]);private Blender[]? _blendersBeforeToken;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043f\u0430\u0440\u0441\u0435\u0440 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0442\u043e\u043a\u0435\u043d, \u043e\u043d \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0431\u043b\u0435\u043d\u0434\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u044b\u043b \u0434\u043e \u044d\u0442\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430. \u042d\u0442\u043e \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0430\u044f \u0434\u0435\u0442\u0430\u043b\u044c, \u043d\u043e \u0431\u0435\u0437 \u043d\u0435\u0451 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u043e \u0441\u044a\u0435\u0437\u0436\u0430\u0442\u044c: \u043f\u0430\u0440\u0441\u0435\u0440 \u0434\u0443\u043c\u0430\u0435\u0442, \u0447\u0442\u043e \u0432\u0435\u0440\u043d\u0443\u043b\u0441\u044f \u043d\u0430\u0437\u0430\u0434, \u0430 \u0431\u043b\u0435\u043d\u0434\u0435\u0440 \u0443\u0436\u0435 \u0443\u0448\u0451\u043b \u0432\u043f\u0435\u0440\u0451\u0434 \u043f\u043e \u0441\u0442\u0430\u0440\u043e\u043c\u0443 \u0434\u0435\u0440\u0435\u0432\u0443.<\/p>\n<h3>FastPeekToken<\/h3>\n<p>\u0415\u0449\u0451 \u043e\u0434\u043d\u0430 \u043f\u043e\u0445\u043e\u0436\u0430\u044f \u0434\u0435\u0442\u0430\u043b\u044c \u2014 fast peek.<\/p>\n<p>\u0412 \u043e\u0431\u044b\u0447\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d \u0447\u0435\u0440\u0435\u0437 \u043b\u0435\u043a\u0441\u0435\u0440 \u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c <code>TextWindow<\/code> \u043d\u0430\u0437\u0430\u0434. \u0412 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u0431\u043b\u0435\u043d\u0434\u0435\u0440:<\/p>\n<pre><code class=\"cs\">private GreenSyntaxToken FastPeekBlendedToken(){    var savedPosition = _lexer.TextWindow.Position;    var blended = _blender.ReadFreshToken(_mode);    _lexer.TextWindow.Reset(savedPosition);    return (GreenSyntaxToken)blended.Token.RequiredNode;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0411\u043b\u0435\u043d\u0434\u0435\u0440 \u0441\u0430\u043c \u0437\u0434\u0435\u0441\u044c \u043d\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u043f\u0430\u0440\u0441\u0435\u0440\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u0435\u0442\u043e\u0434 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043c\u043e\u0442\u0440\u0438\u0442. \u0412\u0430\u0436\u043d\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c <code>TextWindow<\/code>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e <code>ReadFreshToken<\/code> \u043c\u043e\u0436\u0435\u0442 \u0441\u0445\u043e\u0434\u0438\u0442\u044c \u0432 \u043b\u0435\u043a\u0441\u0435\u0440.<\/p>\n<h2>\u041f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u044b\u0439 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0438\u043d\u0433<\/h2>\n<p>\u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043d\u0430\u0447\u0430\u0442\u044c \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0438\u043d\u0433, \u044d\u0442\u043e \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e top-level members.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>using System;state int count = 0;&lt;TextBlock Text=\"Hello\"\/&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e <code>count<\/code>, \u0442\u043e <code>using System;<\/code> \u0438 markup root \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0446\u0435\u043b\u0438\u043a\u043e\u043c. \u042d\u0442\u043e \u0443\u0436\u0435 \u0434\u0430\u0451\u0442 \u0432\u044b\u0438\u0433\u0440\u044b\u0448 \u043d\u0430 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0444\u0430\u0439\u043b\u0430\u0445.<\/p>\n<p>\u0412 \u043f\u0430\u0440\u0441\u0435\u0440\u0435 \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">private bool TryEatReusableTopLevelMember(out GreenAkTopLevelMemberSyntax member){    member = null!;    if (!CanReadIncrementalNodeOrToken())    {        return false;    }    var blended = _blender.ReadNode(_mode);    if (blended.Node is not AkTopLevelMemberSyntax node ||        !CanReuseTopLevelMember(node.Green))    {        return false;    }    _blender = blended.Blender;    _prevTokenTrailingTrivia = ((GreenSyntaxToken?)node.Green.GetLastTerminal())?.GetTrailingTrivia();    member = node.Green;    return true;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e \u043f\u0435\u0440\u0432\u0430\u044f \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u043f\u043e\u0431\u0435\u0434\u0430: \u043f\u0430\u0440\u0441\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u043d\u0435 \u0447\u0438\u0442\u0430\u0442\u044c \u0442\u043e\u043a\u0435\u043d\u044b \u0434\u043b\u044f \u0446\u0435\u043b\u043e\u0439 top-level \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438.<\/p>\n<p>\u041d\u043e \u043f\u043e\u0442\u043e\u043c \u0431\u044b\u0441\u0442\u0440\u043e \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e top-level \u043c\u0430\u043b\u043e. \u0415\u0441\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0441\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u0432\u043d\u0443\u0442\u0440\u0438 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e markup root, \u0432\u0435\u0441\u044c root \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0441\u043e\u0431\u0440\u0430\u043d. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0448\u0430\u0433 \u044d\u0442\u043e \u0438\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0434\u043b\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439.<\/p>\n<h3>State<\/h3>\n<p><code>state<\/code> \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439, \u0438 \u0435\u0433\u043e \u0443\u0434\u043e\u0431\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0441\u043b\u043e\u0442\u043e\u0432:<\/p>\n<pre><code>state int count = 0;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u043c\u044f, \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c keyword, type, equals, initializer \u0438 semicolon.<\/p>\n<pre><code class=\"cs\">private bool TryParseIncrementalStateDeclaration(out GreenStateDeclarationSyntax state){    state = null!;    if (!CanReadIncrementalNodeOrToken() ||        !TryReadIncrementalToken(SyntaxKind.StateKeyword, out var stateKeyword))    {        return false;    }    var type = ParseIncrementalCSharpTypeOrNull();    var name = ParseIncrementalIdentifierName();    var equals = ReadRequiredIncrementalToken(SyntaxKind.EqualsToken);    var initializer = ParseIncrementalStateInitializer();    var semicolon = ReadRequiredIncrementalToken(SyntaxKind.SemicolonToken);    state = GreenSyntaxFactory.StateDeclarationSyntax(        stateKeyword,        type,        name,        equals,        initializer,        semicolon);    return true;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u0443\u0441\u043e\u043a \u0441\u0430\u043c \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f reuse-\u0438\u0442\u044c\u0441\u044f. \u0415\u0441\u043b\u0438 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c, \u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0441\u0432\u0435\u0436\u0438\u0439 \u0442\u043e\u043a\u0435\u043d.<\/p>\n<h3>Command \u0438 inject<\/h3>\n<p><code>command<\/code> \u0438 <code>inject<\/code> \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u0442\u0430\u043a \u0436\u0435:<\/p>\n<pre><code>inject ILogger&lt;DashboardPage&gt; log;command Task Refresh(int userId);<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f \u043d\u0438\u0445 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0447\u0438\u0442\u0430\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 slots:<\/p>\n<pre><code>keywordtype \/ return typenameparameterssemicolon<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>C# parts \u043f\u043e\u043a\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0433\u0440\u0443\u0431\u043e: \u0435\u0441\u043b\u0438 C# type \u0438\u043b\u0438 parameter list \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0438\u0441\u044c, \u043f\u0435\u0440\u0435\u0441\u043e\u0431\u0440\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u043a\u0443\u0441\u043e\u043a \u0447\u0435\u0440\u0435\u0437 Roslyn <code>SyntaxFactory.Parse...<\/code>. \u0413\u043b\u0430\u0432\u043d\u043e\u0435, \u0447\u0442\u043e Akbura-\u043e\u0431\u0432\u044f\u0437\u043a\u0430 \u0443\u0436\u0435 \u0443\u043c\u0435\u0435\u0442 \u0440\u0435\u044e\u0437\u0438\u0442\u044c \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0435 \u0447\u0430\u0441\u0442\u0438.<\/p>\n<h3>Markup<\/h3>\n<p>Markup \u0434\u0430\u0451\u0442 \u0441\u0430\u043c\u044b\u0439 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0432\u044b\u0438\u0433\u0440\u044b\u0448.<\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442:<\/p>\n<pre><code>&lt;StackPanel class=\"card\" gap-4 p-4&gt;    &lt;TextBlock Text=\"Dashboard\"\/&gt;    &lt;Input bind:Value={Search}\/&gt;    &lt;Button OnClick={count++}&gt;Open&lt;\/Button&gt;    &lt;TaskList Items={tasks}\/&gt;&lt;\/StackPanel&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u043e\u043c\u0435\u043d\u044f\u043b <code>Dashboard<\/code> \u043d\u0430 <code>Tasks<\/code>, full reparse \u043f\u0435\u0440\u0435\u0441\u043e\u0431\u0435\u0440\u0451\u0442 \u0432\u0435\u0441\u044c root. \u0418\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e attribute value \u0438\u043b\u0438 text literal, \u0430 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0435 attributes \u0438 child elements \u0432\u0437\u044f\u0442\u044c \u0438\u0437 \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 markup \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0443\u0440\u043e\u0432\u043d\u044f\u0445:<\/p>\n<pre><code>MarkupRootSyntaxMarkupElementSyntaxMarkupStartTagSyntaxMarkupEndTagSyntaxMarkupAttributeSyntaxMarkupContentSyntaxInlineExpressionSyntax<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u043f\u0430\u0440\u0441\u0435\u0440 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0431\u0443\u0435\u0442 reuse-\u0438\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0439 node:<\/p>\n<pre><code class=\"cs\">if (TryReadReusableIncrementalNode&lt;GreenMarkupElementSyntax&gt;(out var element)){    return element;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 node \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u0441 changed range, \u043f\u0430\u0440\u0441\u0435\u0440 \u0438\u0434\u0451\u0442 \u0433\u043b\u0443\u0431\u0436\u0435 \u0438 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u0435\u0433\u043e \u0438\u0437 \u0447\u0430\u0441\u0442\u0435\u0439. \u0422\u0430\u043a outer element \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u043e\u0432\u044b\u043c, \u043d\u043e \u0435\u0433\u043e \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u0451\u043d\u043d\u044b\u0435 child attributes \u0438\u043b\u0438 body items \u043e\u0441\u0442\u0430\u043d\u0443\u0442\u0441\u044f \u0441\u0442\u0430\u0440\u044b\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438.<\/p>\n<p>\u0418\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u044d\u0442\u043e\u043c\u0443 benchmark \u043f\u043e markup \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0445\u043e\u0440\u043e\u0448\u043e: \u0431\u043e\u043b\u044c\u0448\u043e\u0439 markup root \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043c\u043d\u043e\u0433\u043e \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0445 children, \u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0433\u043e attribute \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u0435\u0440\u0435\u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0432\u0435\u0441\u044c \u0441\u043f\u0438\u0441\u043e\u043a.<\/p>\n<h3>Inline Akcss<\/h3>\n<p>Inline Akcss \u0442\u043e\u0436\u0435 \u0445\u043e\u0440\u043e\u0448\u043e \u043b\u043e\u0436\u0438\u0442\u0441\u044f \u043d\u0430 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c:<\/p>\n<pre><code class=\"css\">@akcss {    .card {        Background: White;    }    @utilities {        .gap-(double value) {            RowGap: value * Spacing;        }    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043c \u0435\u0441\u0442\u044c top-level members, body members, selectors, utility parameters \u0438 assignments. \u0412\u0441\u0451 \u044d\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u044f\u0437\u044b\u043a \u0432\u043d\u0443\u0442\u0440\u0438 Akbura.<\/p>\n<p>\u0418\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0434\u043b\u044f Akcss \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0442\u043e\u0442 \u0436\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f:<\/p>\n<pre><code>\u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c reusable node\u0435\u0441\u043b\u0438 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c, \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c childrenC# expressions \u0432\u043d\u0443\u0442\u0440\u0438 assignments \u0447\u0438\u0442\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c helper-\u043e\u043c<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0432\u0430\u0436\u043d\u043e \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0440\u0435\u0436\u0438\u043c \u043b\u0435\u043a\u0441\u0435\u0440\u0430 \u0432 <code>InAkcss<\/code>, \u0438\u043d\u0430\u0447\u0435 <code>@if<\/code>, <code>.card<\/code>, utility selectors \u0438 \u043e\u0431\u044b\u0447\u043d\u0430\u044f Akbura top-level grammar \u043d\u0430\u0447\u043d\u0443\u0442 \u043c\u0435\u0448\u0430\u0442\u044c \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0443.<\/p>\n<h3>CSharpBlockSyntax<\/h3>\n<p>C# blocks \u0432 Akbura \u043d\u0435\u043e\u0431\u044b\u0447\u043d\u044b\u0435. \u0412\u043d\u0443\u0442\u0440\u0438 \u0431\u043b\u043e\u043a\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0431\u044b\u0447\u043d\u044b\u0439 C# statement \u0438 markup:<\/p>\n<pre><code class=\"cs\">if(isOpen){    Console.WriteLine(\"Panel opened\");    &lt;TextBlock Text=\"Opened!\"\/&gt;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 <code>CSharpBlockSyntax<\/code> \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u043f\u0438\u0441\u043e\u043a <code>AkTopLevelMember<\/code>, \u0430 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e C# tokens.<\/p>\n<p>\u0414\u043b\u044f \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043f\u0435\u0440\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0434\u0435\u043b\u0430\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0441\u043b\u0443\u0447\u0430\u0438:<\/p>\n<pre><code>\u0435\u0441\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0441\u044f \u043e\u0434\u0438\u043d raw C# token, \u043f\u0435\u0440\u0435\u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0433\u043e\u0435\u0441\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0441\u044f nested markup, \u0434\u0430\u0442\u044c markup \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u043f\u0430\u0440\u0441\u0435\u0440\u0443 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0440\u0430\u0431\u043e\u0442\u0443\u0435\u0441\u043b\u0438 \u0431\u043b\u043e\u043a \u043d\u0435 \u0437\u0430\u0442\u0440\u043e\u043d\u0443\u0442, \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0446\u0435\u043b\u0438\u043a\u043e\u043c<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>C# parts \u0441\u043b\u043e\u0436\u043d\u0435\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0438\u0434\u0438\u0442 Roslyn. \u0418\u0434\u0435\u0430\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u0442\u044c Roslyn \u0440\u0435\u043f\u0430\u0440\u0441\u043d\u0443\u0441\u0442\u044c \u043a\u0443\u0441\u043e\u043a syntax node \u0441 <code>TextChangeRange<\/code>. \u041d\u043e \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u043e\u0433\u043e \u0443\u0434\u043e\u0431\u043d\u043e\u0433\u043e API \u0434\u043b\u044f \u043e\u0431\u0449\u0435\u0433\u043e \u0441\u043b\u0443\u0447\u0430\u044f \u043d\u0435\u0442. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c raw-\u0442\u043e\u043a\u0435\u043d \u0438 \u043d\u0435 \u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0443\u0433\u0430\u0434\u0430\u0442\u044c \u0432\u0441\u0435 C# grammar cases. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u0443\u043c\u0430\u043b \u0447\u0442\u043e \u043c\u043d\u0435 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 <a href=\"https:\/\/learn.microsoft.com\/ru-ru\/dotnet\/api\/microsoft.codeanalysis.syntaxtree.withchangedtext?view=roslyn-dotnet-4.2.0\" rel=\"noopener noreferrer nofollow\">SyntaxTree.WithChangedText(SourceText)<\/a>, \u043d\u043e \u0443\u0432\u044b \u0438 \u0430\u0445, \u0442\u0430\u043a \u043a\u0430\u043a CSharp \u0431\u043b\u043e\u043a\u0438 \u0443 \u043d\u0430\u0441 \u043d\u0435 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e, \u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u044c\u0441\u044f \u043b\u0435\u043d\u0438\u0432\u043e \u043d\u043e\u0432\u043e\u0435, \u0438 \u0441\u0443\u0434\u044f \u043f\u043e \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0430\u043c  \u0435\u0441\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <a href=\"https:\/\/learn.microsoft.com\/ru-ru\/dotnet\/api\/microsoft.codeanalysis.syntaxtree.withchangedtext?view=roslyn-dotnet-4.2.0\" rel=\"noopener noreferrer nofollow\">SyntaxTree.WithChangedText(SourceText)<\/a>, \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043c\u0435\u0434\u043b\u0435\u043d\u0435\u0435 \u043d\u0430 20%, \u0447\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043b\u043d\u044b\u0439 \u0440\u0435\u043f\u0430\u0440\u0441 \u0432\u0441\u0435\u0433\u043e \u043a\u043e\u0434\u0430.<\/p>\n<h2>\u0422\u0435\u0441\u0442\u044b<\/h2>\n<p>\u0414\u043b\u044f \u0431\u043b\u0435\u043d\u0434\u0435\u0440\u0430 \u0442\u0435\u0441\u0442\u044b \u043d\u0443\u0436\u043d\u044b \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0443\u0440\u043e\u0432\u043d\u044f\u0445.<\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u044d\u0442\u043e <code>Cursor<\/code>.<\/p>\n<p>Cursor \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0445\u043e\u0434\u0438\u0442\u044c \u043f\u043e \u0434\u0435\u0440\u0435\u0432\u0443:<\/p>\n<pre><code class=\"cs\">var cursor = new Blender.Cursor(root);var first = cursor.MoveToFirstChild();<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043e\u043d \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u0432 \u043d\u0443\u0436\u043d\u044b\u0435 node \u0438\u043b\u0438 \u0442\u043e\u043a\u0435\u043d, \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442 zero-width \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0438 \u0443\u043c\u0435\u0435\u0442 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a sibling.<\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u044d\u0442\u043e <code>Reader<\/code>.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 reader \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u0440\u0430\u0442\u044c tokens \u0438\u0437 \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430:<\/p>\n<pre><code class=\"cs\">const string code = \"state count = 0;\";using var lexer = new Lexer(SourceText.From(code));var oldTree = ParseRoot(code);var blender = new Blender(lexer, oldTree, changes: null);var first = blender.ReadToken(Lexer.LexerMode.TopLevel);Assert.Null(first.Node);Assert.Equal(SyntaxKind.StateKeyword, first.Token.Kind);Assert.Equal(\"state \", first.Token.ToFullString());<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410 \u0432\u043d\u0443\u0442\u0440\u0438 changed range \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0432\u0435\u0436\u0438\u0439 \u0442\u043e\u043a\u0435\u043d:<\/p>\n<pre><code class=\"cs\">const string oldCode = \"state count = 0;\";const string newCode = \"param count = 0;\";var change = new TextChangeRange(    new TextSpan(0, \"state\".Length),    \"param\".Length);var blender = new Blender(lexer, oldTree, [change]);var first = blender.ReadToken(Lexer.LexerMode.TopLevel);Assert.Equal(SyntaxKind.ParamKeyword, first.Token.Kind);<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0440\u0435\u0442\u0438\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u044d\u0442\u043e \u0442\u0435\u0441\u0442\u044b \u043f\u0430\u0440\u0441\u0435\u0440\u0430.<\/p>\n<p>\u0421\u0430\u043c\u044b\u0435 \u0432\u0430\u0436\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438:<\/p>\n<pre><code class=\"cs\">Assert.Equal(code, syntax.ToFullString());Assert.Equal(code.Length, syntax.FullWidth);<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code>ToFullString()<\/code> \u043b\u043e\u0432\u0438\u0442 \u043f\u043e\u0442\u0435\u0440\u044e \u0442\u0435\u043a\u0441\u0442\u0430. <code>FullWidth<\/code> \u043b\u043e\u0432\u0438\u0442 \u0441\u0434\u0432\u0438\u0433\u0438 cursor-\u0430 \u0438 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u0443\u0447\u0451\u0442 \u0448\u0438\u0440\u0438\u043d\u044b. \u042d\u0442\u043e \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e: \u0442\u0430\u043a\u0438\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441\u0440\u0430\u0437\u0443 \u043d\u0430\u0448\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u0441\u0442, \u0433\u0434\u0435 generated nodes \u0438\u043b\u0438 raw tokens \u043d\u0435\u0432\u0435\u0440\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u043b\u0438 \u0448\u0438\u0440\u0438\u043d\u0443.<\/p>\n<p>\u0415\u0449\u0451 \u043e\u0434\u0438\u043d \u0432\u0430\u0436\u043d\u044b\u0439 \u0442\u0435\u0441\u0442 \u2014 realistic invalid multi-edit.<\/p>\n<p>\u0421\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u043e\u0439:<\/p>\n<pre><code>oldCode \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439newCode \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439\u0447\u0430\u0441\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0434\u0435\u043b\u0430\u0435\u0442 \u043a\u043e\u0434 \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u044b\u043c\u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432\u0435\u0441\u044c \u0442\u0435\u043a\u0441\u0442\u0438 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0442\u0435\u0441\u0442\u0435 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0437\u0430\u0442\u0440\u0430\u0433\u0438\u0432\u0430\u044e\u0442\u0441\u044f:<\/p>\n<pre><code>\u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0432\u0441\u0442\u0430\u0432\u043a\u0430\u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0439 \u0441\u0435\u043a\u0446\u0438\u0438\u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0441\u0435\u043a\u0446\u0438\u0438 \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0441\u0442\u0430\u043b \u0438\u043d\u0432\u0430\u043b\u0438\u0434\u043d\u044b\u043c\u0432\u0441\u0442\u0430\u0432\u043a\u0430 \u0438\u043d\u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430markupakcssCSharpBlockSyntaxraw C# fragments<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 reuse \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u043e \u0441\u043c\u044b\u0441\u043b\u0443 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">var treeReuseRatio = GetReusableSyntaxNodeRatio(oldSyntax, incremental);Assert.True(treeReuseRatio &gt;= 0.95);<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e \u043d\u0435 \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u043e\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c 95% \u0434\u0435\u0440\u0435\u0432\u0430. \u042d\u0442\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u043e\u0433\u043e \u043a\u0435\u0439\u0441\u0430, \u0433\u0434\u0435 \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0444\u0430\u0439\u043b\u0430 \u043d\u0435 \u043c\u0435\u043d\u044f\u043b\u0430\u0441\u044c. \u0414\u043b\u044f \u043d\u0435\u0433\u043e \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0440\u043e\u0433 \u043f\u043e\u043b\u0435\u0437\u0435\u043d: \u0435\u0441\u043b\u0438 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e \u0441\u043b\u043e\u043c\u0430\u0442\u044c reuse \u0438 \u043d\u0430\u0447\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0432\u0441\u0451 \u0434\u0435\u0440\u0435\u0432\u043e, \u0442\u0435\u0441\u0442 \u0441\u0440\u0430\u0437\u0443 \u0443\u043f\u0430\u0434\u0451\u0442.<\/p>\n<h2>\u0411\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0438<\/h2>\n<p>\u0411\u0435\u0437 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0430 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043b\u0435\u0433\u043a\u043e \u043e\u0431\u043c\u0430\u043d\u0443\u0442\u044c. \u041c\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043e\u0447\u0435\u043d\u044c \u0443\u043c\u043d\u044b\u0439 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0434\u0435\u0440\u0435\u0432\u043e, \u043d\u043e \u0442\u0440\u0430\u0442\u0438\u0442 \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043d\u0430 \u043f\u043e\u0438\u0441\u043a \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u043d\u043e\u0434, \u0447\u0442\u043e \u043f\u043e\u043b\u043d\u044b\u0439 \u0440\u0435\u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0431\u044b\u0441\u0442\u0440\u0435\u0435.<\/p>\n<p>\u0422\u0430\u043a \u0438 \u0431\u044b\u043b\u043e \u043d\u0430 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445. \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0441 C# blocks: \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 \u043f\u043e\u043b\u043d\u043e\u0433\u043e \u0440\u0435\u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430. \u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0431\u044b\u043b\u0430 \u0432 \u043b\u0438\u0448\u043d\u0435\u043c \u043e\u0431\u0445\u043e\u0434\u0435 \u0434\u0435\u0440\u0435\u0432\u0430 \u0438 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0434\u043e\u0440\u043e\u0433\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u043d\u043e\u0434.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0439 \u201c\u0440\u0435\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u044b\u0439\u201d \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a \u0441\u0442\u0430\u043b \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043a\u0443\u0434\u0430 \u043f\u0440\u0438\u044f\u0442\u043d\u0435\u0435:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">Method<\/p>\n<\/th>\n<th>\n<p align=\"left\">Mean<\/p>\n<\/th>\n<th>\n<p align=\"left\">Error<\/p>\n<\/th>\n<th>\n<p align=\"left\">StdDev<\/p>\n<\/th>\n<th>\n<p align=\"left\">Ratio<\/p>\n<\/th>\n<th>\n<p align=\"left\">RatioSD<\/p>\n<\/th>\n<th>\n<p align=\"left\">Gen0<\/p>\n<\/th>\n<th>\n<p align=\"left\">Gen1<\/p>\n<\/th>\n<th>\n<p align=\"left\">Allocated<\/p>\n<\/th>\n<th>\n<p align=\"left\">Alloc Ratio<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">FullReparseAfterRealisticInvalidEdit<\/p>\n<\/td>\n<td>\n<p align=\"left\">16,456.2 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">242.01 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">202.09 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.00<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.02<\/p>\n<\/td>\n<td>\n<p align=\"left\">1062.5000<\/p>\n<\/td>\n<td>\n<p align=\"left\">375.0000<\/p>\n<\/td>\n<td>\n<p align=\"left\">6790.3 KB<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.00<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">IncrementalParseAfterRealisticInvalidEdit<\/p>\n<\/td>\n<td>\n<p align=\"left\">293.7 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">2.54 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">2.49 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.02<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.00<\/p>\n<\/td>\n<td>\n<p align=\"left\">23.9258<\/p>\n<\/td>\n<td>\n<p align=\"left\">3.9063<\/p>\n<\/td>\n<td>\n<p align=\"left\">153.69 KB<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.02<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0432 \u044d\u0442\u043e\u043c \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0432 \u0434\u0435\u0441\u044f\u0442\u043a\u0438 \u0440\u0430\u0437 \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0438 \u0441\u0438\u043b\u044c\u043d\u043e \u043c\u0435\u043d\u044c\u0448\u0435 \u0430\u043b\u043b\u043e\u0446\u0438\u0440\u0443\u0435\u0442.<\/p>\n<p>Markup benchmark \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">Method<\/p>\n<\/th>\n<th>\n<p align=\"left\">ChildCount<\/p>\n<\/th>\n<th>\n<p align=\"left\">Mean<\/p>\n<\/th>\n<th>\n<p align=\"left\">Error<\/p>\n<\/th>\n<th>\n<p align=\"left\">StdDev<\/p>\n<\/th>\n<th>\n<p align=\"left\">Ratio<\/p>\n<\/th>\n<th>\n<p align=\"left\">RatioSD<\/p>\n<\/th>\n<th>\n<p align=\"left\">Gen0<\/p>\n<\/th>\n<th>\n<p align=\"left\">Gen1<\/p>\n<\/th>\n<th>\n<p align=\"left\">Gen2<\/p>\n<\/th>\n<th>\n<p align=\"left\">Allocated<\/p>\n<\/th>\n<th>\n<p align=\"left\">Alloc Ratio<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">FullParseAfterMarkupEdit<\/p>\n<\/td>\n<td>\n<p align=\"left\">40<\/p>\n<\/td>\n<td>\n<p align=\"left\">1,019.04 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">20.167 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">39.808 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.00<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.05<\/p>\n<\/td>\n<td>\n<p align=\"left\">68.3594<\/p>\n<\/td>\n<td>\n<p align=\"left\">17.5781<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.9766<\/p>\n<\/td>\n<td>\n<p align=\"left\">495.04 KB<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.00<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">IncrementalParseAfterMarkupEdit<\/p>\n<\/td>\n<td>\n<p align=\"left\">40<\/p>\n<\/td>\n<td>\n<p align=\"left\">34.20 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.446 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.395 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.03<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.00<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.3994<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.1597<\/p>\n<\/td>\n<td>\n<p align=\"left\">&#8212;<\/p>\n<\/td>\n<td>\n<p align=\"left\">57.87 KB<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.12<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">FullParseAfterMarkupEdit<\/p>\n<\/td>\n<td>\n<p align=\"left\">200<\/p>\n<\/td>\n<td>\n<p align=\"left\">6,230.84 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">116.679 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">204.354 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.00<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.05<\/p>\n<\/td>\n<td>\n<p align=\"left\">39.0625<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.6250<\/p>\n<\/td>\n<td>\n<p align=\"left\">7.8125<\/p>\n<\/td>\n<td>\n<p align=\"left\">2411.15 KB<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.00<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">IncrementalParseAfterMarkupEdit<\/p>\n<\/td>\n<td>\n<p align=\"left\">200<\/p>\n<\/td>\n<td>\n<p align=\"left\">80.32 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.592 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">2.911 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.01<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.00<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.8691<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.7090<\/p>\n<\/td>\n<td>\n<p align=\"left\">&#8212;<\/p>\n<\/td>\n<td>\n<p align=\"left\">97.94 KB<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.04<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">FullParseAfterMarkupEdit<\/p>\n<\/td>\n<td>\n<p align=\"left\">1000<\/p>\n<\/td>\n<td>\n<p align=\"left\">26,286.78 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">355.715 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">315.332 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.00<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.02<\/p>\n<\/td>\n<td>\n<p align=\"left\">218.7500<\/p>\n<\/td>\n<td>\n<p align=\"left\">125.0000<\/p>\n<\/td>\n<td>\n<p align=\"left\">93.7500<\/p>\n<\/td>\n<td>\n<p align=\"left\">11686.09 KB<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.00<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">IncrementalParseAfterMarkupEdit<\/p>\n<\/td>\n<td>\n<p align=\"left\">1000<\/p>\n<\/td>\n<td>\n<p align=\"left\">342.71 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">6.809 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.573 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.01<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.00<\/p>\n<\/td>\n<td>\n<p align=\"left\">46.8750<\/p>\n<\/td>\n<td>\n<p align=\"left\">6.8359<\/p>\n<\/td>\n<td>\n<p align=\"left\">&#8212;<\/p>\n<\/td>\n<td>\n<p align=\"left\">291.11 KB<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.02<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0422\u0430\u043c \u0432\u044b\u0438\u0433\u0440\u044b\u0448 \u043e\u0433\u0440\u043e\u043c\u043d\u044b\u0439, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e markup \u0434\u0435\u0440\u0435\u0432\u043e \u0448\u0438\u0440\u043e\u043a\u043e\u0435: \u043c\u043d\u043e\u0433\u043e \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432, \u043c\u043d\u043e\u0433\u043e \u0434\u0435\u0442\u0435\u0439, \u043c\u043d\u043e\u0433\u043e \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432. \u0411\u043b\u0435\u043d\u0434\u0435\u0440 \u0438 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u043a\u0430\u043a \u0440\u0430\u0437 \u0445\u043e\u0440\u043e\u0448\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043d\u0430 \u0442\u0430\u043a\u0438\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u0445.<\/p>\n<p>C# block benchmark \u0441\u043a\u0440\u043e\u043c\u043d\u0435\u0435. \u042d\u0442\u043e \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e. C# raw fragments \u0445\u0443\u0436\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0442 \u0434\u043b\u044f slot-level reuse, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0438\u0445 \u0441\u043f\u0440\u044f\u0442\u0430\u043d \u0434\u0440\u0443\u0433\u043e\u0439 \u044f\u0437\u044b\u043a. \u041d\u043e \u0434\u0430\u0436\u0435 \u0442\u0430\u043c \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0431\u044b\u0441\u0442\u0440\u0435\u0435 full reparse \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f\u0445.<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">Method<\/p>\n<\/th>\n<th>\n<p align=\"left\">StatementCount<\/p>\n<\/th>\n<th>\n<p align=\"left\">Mean<\/p>\n<\/th>\n<th>\n<p align=\"left\">Error<\/p>\n<\/th>\n<th>\n<p align=\"left\">StdDev<\/p>\n<\/th>\n<th>\n<p align=\"left\">Median<\/p>\n<\/th>\n<th>\n<p align=\"left\">Ratio<\/p>\n<\/th>\n<th>\n<p align=\"left\">RatioSD<\/p>\n<\/th>\n<th>\n<p align=\"left\">Gen0<\/p>\n<\/th>\n<th>\n<p align=\"left\">Gen1<\/p>\n<\/th>\n<th>\n<p align=\"left\">Allocated<\/p>\n<\/th>\n<th>\n<p align=\"left\">Alloc Ratio<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">FullParseAfterCSharpBlockEdit<\/p>\n<\/td>\n<td>\n<p align=\"left\">40<\/p>\n<\/td>\n<td>\n<p align=\"left\">32.59 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.640 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.978 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">32.08 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.00<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.04<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.4604<\/p>\n<\/td>\n<td>\n<p align=\"left\">2.5024<\/p>\n<\/td>\n<td>\n<p align=\"left\">58.17 KB<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.00<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">IncrementalParseAfterCSharpBlockEdit<\/p>\n<\/td>\n<td>\n<p align=\"left\">40<\/p>\n<\/td>\n<td>\n<p align=\"left\">13.62 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.258 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.241 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">13.53 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.42<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.01<\/p>\n<\/td>\n<td>\n<p align=\"left\">6.9885<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.8698<\/p>\n<\/td>\n<td>\n<p align=\"left\">42.93 KB<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.74<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">FullParseAfterCSharpBlockEdit<\/p>\n<\/td>\n<td>\n<p align=\"left\">200<\/p>\n<\/td>\n<td>\n<p align=\"left\">113.77 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">2.267 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.029 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">112.48 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.00<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.05<\/p>\n<\/td>\n<td>\n<p align=\"left\">17.8223<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.4648<\/p>\n<\/td>\n<td>\n<p align=\"left\">110.42 KB<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.00<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">IncrementalParseAfterCSharpBlockEdit<\/p>\n<\/td>\n<td>\n<p align=\"left\">200<\/p>\n<\/td>\n<td>\n<p align=\"left\">37.00 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.721 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.011 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">36.59 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.33<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.01<\/p>\n<\/td>\n<td>\n<p align=\"left\">7.9346<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.9766<\/p>\n<\/td>\n<td>\n<p align=\"left\">48.79 KB<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.44<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">FullParseAfterCSharpBlockEdit<\/p>\n<\/td>\n<td>\n<p align=\"left\">1000<\/p>\n<\/td>\n<td>\n<p align=\"left\">493.72 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">9.835 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.312 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">485.26 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.00<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.04<\/p>\n<\/td>\n<td>\n<p align=\"left\">69.3359<\/p>\n<\/td>\n<td>\n<p align=\"left\">28.3203<\/p>\n<\/td>\n<td>\n<p align=\"left\">432.38 KB<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.00<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">IncrementalParseAfterCSharpBlockEdit<\/p>\n<\/td>\n<td>\n<p align=\"left\">1000<\/p>\n<\/td>\n<td>\n<p align=\"left\">149.73 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">2.957 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.859 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">147.43 us<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.30<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.01<\/p>\n<\/td>\n<td>\n<p align=\"left\">11.9629<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.4648<\/p>\n<\/td>\n<td>\n<p align=\"left\">74.15 KB<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.17<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h2>\u0418\u0442\u043e\u0433<\/h2>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u043f\u0435\u0440\u0432\u044b\u0439 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0441\u043b\u043e\u0439 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0441\u0435\u0440\u0430.<\/p>\n<p>\u041c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 <code>Blender<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043c\u0435\u0435\u0442 \u0441\u043c\u0435\u0448\u0438\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u043e\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u043e\u0432 \u0438 \u0441\u0432\u0435\u0436\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u044b \u0438\u0437 \u043b\u0435\u043a\u0441\u0435\u0440\u0430. \u0414\u043e\u0431\u0430\u0432\u0438\u043b\u0438 <code>Cursor<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u0441\u0442\u0430\u0440\u043e\u043c\u0443 \u0434\u0435\u0440\u0435\u0432\u0443 \u0447\u0435\u0440\u0435\u0437 <code>SyntaxNodeOrToken<\/code>. \u0414\u043e\u0431\u0430\u0432\u0438\u043b\u0438 <code>Reader<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 <code>TextChangeRange<\/code>, <code>_changeDelta<\/code>, changed ranges \u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0433\u043e reuse.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043f\u0430\u0440\u0441\u0435\u0440 \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0438 \u043d\u0430\u0447\u0430\u043b \u0447\u0438\u0442\u0430\u0442\u044c \u0442\u043e\u043a\u0435\u043d\u044b \u0447\u0435\u0440\u0435\u0437 \u0431\u043b\u0435\u043d\u0434\u0435\u0440. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0435\u044e\u0437 \u0431\u044b\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 top-level members, \u043f\u043e\u0442\u043e\u043c \u043f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c \u0431\u043e\u043b\u0435\u0435 \u043c\u0435\u043b\u043a\u0438\u0435 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0434\u043b\u044f <code>state<\/code>, <code>command<\/code>, <code>inject<\/code>, markup, inline Akcss \u0438 <code>CSharpBlockSyntax<\/code>.<\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0448\u0430\u0433 \u2014 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0430. Syntax tree \u0443\u0436\u0435 \u0435\u0441\u0442\u044c, \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0443\u0436\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0442\u0435\u043a\u0441\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 <code>ToFullString()<\/code>, \u0448\u0438\u0440\u0438\u043d\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 <code>FullWidth<\/code>, \u0430 \u043f\u0430\u0440\u0441\u0435\u0440 \u0443\u043c\u0435\u0435\u0442 \u0436\u0438\u0442\u044c \u0432 IDE-\u0440\u0435\u0436\u0438\u043c\u0435. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0447\u0430\u0442\u044c \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441\u044b \u043f\u043e\u0441\u043b\u043e\u0436\u043d\u0435\u0435: \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 <code>state<\/code>, \u043a\u0430\u043a \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>bind<\/code>, \u043a\u0430\u043a \u043d\u0430\u0439\u0442\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043a\u0430\u043a \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c <code>command<\/code>, \u0438 \u043a\u0430\u043a \u0432\u0441\u0451 \u044d\u0442\u043e \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0432 \u0440\u0430\u0431\u043e\u0447\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c \u044f\u0437\u044b\u043a\u0430. \u0418 \u043a\u0430\u043a \u044d\u0442\u043e \u0435\u0449\u0435 \u0432\u0441\u0435 \u0441\u0432\u044f\u0437\u0430\u0442\u044c \u0441 \u043a\u0443\u0441\u043a\u0430\u043c\u0438 c# \u043a\u043e\u0434\u0430.<\/p>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1046103\/\">https:\/\/habr.com\/ru\/articles\/1046103\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0423\u0440\u0430, \u0432\u043e\u0442 \u0438 \u0434\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c \u043c\u044b \u0434\u043e \u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430, \u0437\u0430\u0447\u0435\u043c \u043c\u044b \u0432\u043e\u043e\u0431\u0449\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0440\u043e\u0441\u043b\u0438\u043d\u043e\u0432\u043a\u0441\u043a\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0435\u0440\u0435\u0432\u0430. \u0412 \u043f\u0440\u043e\u0448\u043b\u044b\u0439 \u0440\u0430\u0437 \u043c\u044b \u0434\u043e\u0448\u043b\u0438 \u0434\u043e \u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430, \u043a\u043e\u0433\u0434\u0430 .akbura \u0444\u0430\u0439\u043b \u0443\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u0432 lossless syntax tree: \u043b\u0435\u043a\u0441\u0435\u0440 \u0447\u0438\u0442\u0430\u0435\u0442 \u0442\u043e\u043a\u0435\u043d\u044b, \u043f\u0430\u0440\u0441\u0435\u0440 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 state, param, inject, useEffect, command, markup, inline Akcss \u0438 C# fragments. \u042d\u0442\u043e \u0443\u0436\u0435 \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u044f\u0437\u044b\u043a, \u043d\u043e \u0434\u043b\u044f IDE \u044d\u0442\u043e\u0433\u043e \u043c\u0430\u043b\u043e.\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u041f\u0438\u0448\u0435\u043c \u043f\u0430\u0440\u0441\u0435\u0440\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0431\u043b\u0435\u043d\u0434\u0435\u0440\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0443\u0414\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0430\u0418\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u043c Language Server Protocol \u0438 \u0434\u0435\u043b\u0430\u0435\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0432 Visual Studio\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434\u0417\u0430\u0447\u0435\u043c \u043d\u0443\u0436\u0435\u043d \u0431\u043b\u0435\u043d\u0434\u0435\u0440\u041e\u0431\u044b\u0447\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u044f\u043c\u043e\u043b\u0438\u043d\u0435\u0439\u043d\u043e. \u0415\u043c\u0443 \u0434\u0430\u044e\u0442 \u0442\u0435\u043a\u0441\u0442, \u043e\u043d \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043b\u0435\u043a\u0441\u0435\u0440, \u043b\u0435\u043a\u0441\u0435\u0440 \u043e\u0442\u0434\u0430\u0451\u0442 \u0442\u043e\u043a\u0435\u043d\u044b, \u043f\u0430\u0440\u0441\u0435\u0440 \u0441\u0442\u0440\u043e\u0438\u0442 \u0434\u0435\u0440\u0435\u0432\u043e. \u0415\u0441\u043b\u0438 \u0444\u0430\u0439\u043b \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439, \u044d\u0442\u043e \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e. \u0415\u0441\u043b\u0438 \u0444\u0430\u0439\u043b \u0431\u043e\u043b\u044c\u0448\u043e\u0439, \u0442\u043e\u0436\u0435 \u0442\u0435\u0440\u043f\u0438\u043c\u043e. \u041d\u043e IDE \u0436\u0438\u0432\u0451\u0442 \u0432 \u0434\u0440\u0443\u0433\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435.\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0444\u0430\u0439\u043b \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u0438 \u043d\u0435 \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u0442 \u043a\u043d\u043e\u043f\u043a\u0443 Parse. \u041e\u043d \u043f\u0435\u0447\u0430\u0442\u0430\u0435\u0442. \u041f\u043e\u0442\u043e\u043c \u0441\u0442\u0438\u0440\u0430\u0435\u0442. \u041f\u043e\u0442\u043e\u043c \u0441\u043d\u043e\u0432\u0430 \u043f\u0435\u0447\u0430\u0442\u0430\u0435\u0442. \u0418\u043d\u043e\u0433\u0434\u0430 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u0441\u0438\u043c\u0432\u043e\u043b \u0432 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u0444\u0430\u0439\u043b\u0430:state int count = 0;\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0442\u0430\u043b\u043e \u0442\u0430\u043a:state int total = 0;\u0421 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u044d\u0442\u043e \u043d\u043e\u0432\u044b\u0439 \u0442\u0435\u043a\u0441\u0442. \u0417\u043d\u0430\u0447\u0438\u0442 \u043c\u043e\u0436\u043d\u043e \u0441\u043d\u043e\u0432\u0430 \u043f\u0440\u043e\u0439\u0442\u0438 \u0432\u0435\u0441\u044c \u0444\u0430\u0439\u043b \u043e\u0442 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430 \u0434\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e. \u041d\u043e \u0435\u0441\u043b\u0438 \u0432 \u0444\u0430\u0439\u043b\u0435 \u0442\u044b\u0441\u044f\u0447\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, markup \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u043a\u0440\u0430\u043d\u043e\u0432, inline Akcss \u0438 \u043a\u0443\u0447\u0430 C# blocks, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0430\u043d\u043d\u0430\u044f \u043a\u0430\u0440\u0442\u0438\u043d\u0430: \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0438\u0437\u043c\u0435\u043d\u0438\u043b count, \u0430 \u043c\u044b \u0437\u0430\u043d\u043e\u0432\u043e \u0441\u0442\u0440\u043e\u0438\u043c \u0432\u0441\u0451 \u0434\u0435\u0440\u0435\u0432\u043e.\u0412 \u043e\u0431\u044b\u0447\u043d\u043e\u043c compiler pipeline \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u043e. \u0412 IDE \u044d\u0442\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u043c\u0435\u0448\u0430\u0442\u044c. \u041f\u043e\u0434\u0441\u0432\u0435\u0442\u043a\u0430, diagnostics, completion, semantic model \u2014 \u0432\u0441\u0451 \u044d\u0442\u043e \u0437\u0430\u0432\u044f\u0437\u0430\u043d\u043e \u043d\u0430 \u0447\u0430\u0441\u0442\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u0435\u0440\u0435\u0432\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0438 \u043f\u0435\u0440\u0435\u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0443 \u0447\u0430\u0441\u0442\u044c, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u0437\u0430\u0442\u0440\u043e\u043d\u0443\u043b\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435.\u0412\u043e\u0442 \u0437\u0434\u0435\u0441\u044c \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u043b\u0435\u043d\u0434\u0435\u0440.\u0418\u0434\u0435\u044f \u0431\u043b\u0435\u043d\u0434\u0435\u0440\u0430 \u043f\u0440\u043e\u0441\u0442\u0430\u044f: \u043f\u0430\u0440\u0441\u0435\u0440 \u0432\u0441\u0451 \u0435\u0449\u0451 \u0445\u043e\u0447\u0435\u0442 \u043b\u0438\u043d\u0435\u0439\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a. \u041e\u043d \u043d\u0435 \u0445\u043e\u0447\u0435\u0442 \u0434\u0443\u043c\u0430\u0442\u044c, \u043e\u0442\u043a\u0443\u0434\u0430 \u043f\u0440\u0438\u0448\u0451\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442. \u0420\u0430\u043d\u044c\u0448\u0435 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0431\u044b\u043b \u043e\u0434\u0438\u043d \u2014 \u043b\u0435\u043a\u0441\u0435\u0440. \u0422\u0435\u043f\u0435\u0440\u044c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432 \u0434\u0432\u0430:\u0441\u0442\u0430\u0440\u043e\u0435 syntax tree  =&gt; \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0435 \u0443\u0437\u043b\u044b \u0438 \u0442\u043e\u043a\u0435\u043d\u044b\u043d\u043e\u0432\u044b\u0439 SourceText    =&gt; \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u043d\u043e\u0432\u043e \u043b\u0435\u043a\u0441\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0451\u043d\u043d\u044b\u0435 \u043c\u0435\u0441\u0442\u0430\u0411\u043b\u0435\u043d\u0434\u0435\u0440 \u0441\u0442\u043e\u0438\u0442 \u043c\u0435\u0436\u0434\u0443 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u043c, \u043b\u0435\u043a\u0441\u0435\u0440\u043e\u043c \u0438 \u0441\u0442\u0430\u0440\u044b\u043c \u0434\u0435\u0440\u0435\u0432\u043e\u043c. \u041f\u0430\u0440\u0441\u0435\u0440 \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442: \u0434\u0430\u0439 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d \u0438\u043b\u0438 node. \u0411\u043b\u0435\u043d\u0434\u0435\u0440 \u0441\u043c\u043e\u0442\u0440\u0438\u0442 \u043d\u0430 \u043f\u043e\u0437\u0438\u0446\u0438\u044e, \u0441\u043c\u043e\u0442\u0440\u0438\u0442 \u043d\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438 \u0440\u0435\u0448\u0430\u0435\u0442:\u0435\u0441\u043b\u0438 \u0441\u0442\u0430\u0440\u044b\u0439 \u0443\u0437\u0435\u043b \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u0435\u043d =&gt; \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0439 \u0443\u0437\u0435\u043b\u0435\u0441\u043b\u0438 \u043c\u0435\u0441\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u043e\u0441\u044c      =&gt; \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0432\u0435\u0436\u0438\u0439 token \u0438\u0437 lexer-\u0430\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0443\u0434\u0430\u0447\u043d\u043e\u0435. \u041e\u043d \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043c\u0435\u0448\u0438\u0432\u0430\u0435\u0442 \u0441\u0442\u0430\u0440\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 \u0438 \u043d\u043e\u0432\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0442\u043e\u043a\u0435\u043d\u043e\u0432.TextChangeRange\u041d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0432\u0441\u0451 \u0441 TextChangeRange. \u042d\u0442\u043e \u0442\u0438\u043f \u0438\u0437 Roslyn. \u041e\u043d \u0433\u043e\u0432\u043e\u0440\u0438\u0442, \u043a\u0430\u043a\u043e\u0439 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0431\u044b\u043b \u0437\u0430\u043c\u0435\u043d\u0451\u043d \u0438 \u043a\u0430\u043a\u043e\u0439 \u0434\u043b\u0438\u043d\u044b \u0441\u0442\u0430\u043b \u043d\u043e\u0432\u044b\u0439 \u043a\u0443\u0441\u043e\u043a.\u0423\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u043e:var change = new TextChangeRange(    new TextSpan(start: 10, length: 5),    newLength: 8);\u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442:\u0432 \u0441\u0442\u0430\u0440\u043e\u043c \u0442\u0435\u043a\u0441\u0442\u0435 \u0441 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 10 \u0431\u044b\u043b\u043e 5 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432\u0432 \u043d\u043e\u0432\u043e\u043c \u0442\u0435\u043a\u0441\u0442\u0435 \u043d\u0430 \u044d\u0442\u043e\u043c \u043c\u0435\u0441\u0442\u0435 \u0442\u0435\u043f\u0435\u0440\u044c 8 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432\u0412\u0430\u0436\u043d\u043e, \u0447\u0442\u043e TextChangeRange \u0445\u0440\u0430\u043d\u0438\u0442 span \u0432 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u0445 \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430. \u0410 \u043f\u0430\u0440\u0441\u0435\u0440 \u0447\u0438\u0442\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u0442\u0435\u043a\u0441\u0442. \u0417\u043d\u0430\u0447\u0438\u0442 \u043d\u0430\u043c \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c old positions \u0438 new positions.\u041f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440:old: state count = 0;new: state counter = 0;\u041c\u044b \u0437\u0430\u043c\u0435\u043d\u0438\u043b\u0438 count \u043d\u0430 counter. \u0421\u0442\u0430\u0440\u044b\u0439 \u043a\u0443\u0441\u043e\u043a \u0434\u043b\u0438\u043d\u043e\u0439 5, \u043d\u043e\u0432\u044b\u0439 \u0434\u043b\u0438\u043d\u043e\u0439 7. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u0441\u0435 \u0441\u0442\u0430\u0440\u044b\u0435 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0441\u043f\u0440\u0430\u0432\u0430 \u043e\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u0434\u0432\u0438\u043d\u0443\u043b\u0438\u0441\u044c \u043d\u0430 +2.\u0412\u043e\u0442 \u044d\u0442\u043e \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0432 \u0431\u043b\u0435\u043d\u0434\u0435\u0440\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u043a\u0430\u043a _changeDelta.private readonly int _changeDelta;\u0415\u0441\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u043e, \u0432\u0441\u0451 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u043e\u0441\u0442\u043e:newPosition = oldPosition + changeDelta\u0415\u0441\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e, \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u0441\u0432\u0435\u0440\u043d\u0443\u0442\u044c:var collapsed = TextChangeRange.Collapse(changes);\u041d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e. \u0414\u0430 \u0438 \u043a \u0442\u043e\u043c\u0443 \u0436\u0435 \u0441\u0430\u043c\u0438 Roslyn \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u0442\u0430\u043a \u0436\u0435. \u042d\u0442\u043e \u043a\u0441\u0442\u0430\u0442\u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0443\u0434\u0438\u0432\u043b\u044f\u0435\u0442, \u0447\u0442\u043e \u043e\u043d\u0438 \u0434\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043b\u0438 \u044d\u0442\u0443 \u0442\u0443\u0434\u0443\u0448\u043a\u0443, \u0432\u0438\u0434\u0438\u043c\u043e \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0441\u043b\u043e\u0436\u043d\u043e \u0435\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c, \u043d\u0443 \u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430 \u0442\u0430\u043a \u043a\u0430\u043a \u0438\u0445 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0438 \u0442\u0430\u043a \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u044b\u0441\u0442\u0440.\u0412 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 Blender \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u0442\u0430\u0440\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0438 \u043d\u0430\u0431\u043e\u0440 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439:public Blender(    Lexer lexer,    AkburaSyntax oldTree,    IEnumerable&lt;TextChangeRange&gt; changes){    _lexer = lexer;    _changes = ImmutableStack&lt;TextChangeRange&gt;.Empty;    if (changes != null)    {        var collapsed = TextChangeRange.Collapse(changes);        _changes = _changes.Push(ExtendToAffectedRange(oldTree, collapsed));    }    if (oldTree == null)    {        _oldTreeCursor = default;        _newPosition = lexer.TextWindow.Position;    }    else    {        _oldTreeCursor = new Cursor(oldTree).MoveToFirstChild();        _newPosition = 0;    }    _changeDelta = 0;}ExtendToAffectedRange \u043f\u043e\u043a\u0430 \u043f\u043e\u0447\u0442\u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u0442. \u0412 Roslyn ExtendToAffectedRange \u0443\u0441\u0442\u0440\u043e\u0435\u043d \u0441\u043b\u043e\u0436\u043d\u0435\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e C# grammar \u0438\u043c\u0435\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u043c\u0435\u0441\u0442, \u0433\u0434\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u0441\u043c\u044b\u0441\u043b \u0441\u043e\u0441\u0435\u0434\u043d\u0435\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430 \u0438\u043b\u0438 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438. \u0412 Akbura \u043d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u044f \u043e\u0441\u0442\u0430\u0432\u0438\u043b \u043a\u043e\u043d\u0441\u0435\u0440\u0432\u0430\u0442\u0438\u0432\u043d\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c. \u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0441\u043e\u043c\u043d\u0435\u043d\u0438\u0435, \u043f\u0440\u043e\u0449\u0435 \u043d\u0435 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u0437\u0435\u043b. \u0413\u043b\u0430\u0432\u043d\u0430\u044f \u0446\u0435\u043b\u044c \u043f\u0435\u0440\u0432\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u2014 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u043e\u0442\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c.BlendedNode\u041f\u0430\u0440\u0441\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0443 \u0431\u043b\u0435\u043d\u0434\u0435\u0440\u0430 \u0434\u0432\u0435 \u0440\u0430\u0437\u043d\u044b\u0435 \u0432\u0435\u0449\u0438:\u0434\u0430\u0439 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d\u0434\u0430\u0439 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 reusable node\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0443\u0436\u0435\u043d \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043c\u0435\u0435\u0442 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043b\u0438\u0431\u043e \u0441\u0442\u0430\u0440\u0443\u044e \u043a\u0440\u0430\u0441\u043d\u0443\u044e-\u043d\u043e\u0434\u0443, \u043b\u0438\u0431\u043e \u0442\u043e\u043a\u0435\u043d.\u0412 Akbura \u043e\u043d \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:internal readonly struct BlendedNode{    public readonly AkburaSyntax? Node;    public readonly SyntaxToken Token;    public readonly Blender Blender;    public BlendedNode(AkburaSyntax? node, SyntaxToken token, Blender blender)    {        Node = node;        Token = token;        Blender = blender;    }}\u0417\u0434\u0435\u0441\u044c \u043d\u0435\u0442 \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438. \u042d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0447\u0442\u0435\u043d\u0438\u044f.\u0415\u0441\u043b\u0438 Node != null, \u0431\u043b\u0435\u043d\u0434\u0435\u0440 \u0441\u043c\u043e\u0433 \u0432\u0437\u044f\u0442\u044c \u043a\u0443\u0441\u043e\u043a \u0438\u0437 \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0446\u0435\u043b\u044b\u0439 GreenStateDeclarationSyntax \u0438\u043b\u0438 GreenMarkupRootSyntax.\u0415\u0441\u043b\u0438 \u043f\u0440\u0438\u0448\u0451\u043b Token, \u0437\u043d\u0430\u0447\u0438\u0442 \u0441\u0442\u0430\u0440\u044b\u0439 \u0443\u0437\u0435\u043b \u043d\u0435 \u043f\u043e\u0434\u043e\u0448\u0451\u043b, \u0438 \u0431\u043b\u0435\u043d\u0434\u0435\u0440 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043b \u043d\u043e\u0432\u044b\u0439 \u0442\u043e\u043a\u0435\u043d \u0438\u0437 \u043b\u0435\u043a\u0441\u0435\u0440\u0430.\u0422\u0440\u0435\u0442\u044c\u0435 \u043f\u043e\u043b\u0435 \u2014 Blender. \u042d\u0442\u043e \u0432\u0430\u0436\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c.Blender \u0441\u0434\u0435\u043b\u0430\u043d \u0438\u043c\u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u043c. \u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u0447\u0438\u0442\u0430\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442, \u0441\u0442\u0430\u0440\u044b\u0439 \u0431\u043b\u0435\u043d\u0434\u0435\u0440 \u043d\u0435 \u043c\u0443\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u0430\u0440\u0443\u0436\u0443. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u0431\u043b\u0435\u043d\u0434\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0436\u0435 \u0437\u043d\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 cursor \u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 change state.\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0447\u0442\u0435\u043d\u0438\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:var first = blender.ReadToken(Lexer.LexerMode.TopLevel);var second = first.Blender.ReadToken(Lexer.LexerMode.TopLevel);\u042d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432. \u041c\u043e\u0436\u043d\u043e \u044f\u0432\u043d\u043e \u0432\u0438\u0434\u0435\u0442\u044c, \u0447\u0442\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0448\u0430\u0433 \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0435\u0440\u043d\u0443\u043b \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u0448\u0430\u0433.Cursor\u0427\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e, \u0435\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u043a\u0430\u043a-\u0442\u043e \u043e\u0431\u0445\u043e\u0434\u0438\u0442\u044c. \u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0438\u0441\u043a\u0430\u0442\u044c \u0443\u0437\u0435\u043b \u043f\u043e \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0447\u0435\u0440\u0435\u0437 tree APIs, \u043d\u043e \u044d\u0442\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u0441\u0442\u0430\u043d\u0435\u0442 \u0434\u043e\u0440\u043e\u0433\u043e. \u0411\u043b\u0435\u043d\u0434\u0435\u0440 \u0447\u0438\u0442\u0430\u0435\u0442 \u043f\u043e\u0442\u043e\u043a \u0441\u043b\u0435\u0432\u0430 \u043d\u0430\u043f\u0440\u0430\u0432\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438 \u0441\u0442\u0430\u0440\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0443\u0434\u043e\u0431\u043d\u043e \u043e\u0431\u0445\u043e\u0434\u0438\u0442\u044c \u0441\u043b\u0435\u0432\u0430 \u043d\u0430\u043f\u0440\u0430\u0432\u043e.\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0435\u0441\u0442\u044c Blender.Cursor.internal readonly struct Cursor{    private readonly SyntaxNodeOrToken _current;    private readonly PathNode? _parent;    private readonly int _indexInParent;}Cursor \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 root:public Cursor(AkburaSyntax root)    : this(new SyntaxNodeOrToken(root), parent: null, indexInParent: 0){}\u041d\u043e \u0441\u0430\u043c root \u043d\u0430\u043c \u043e\u0431\u044b\u0447\u043d\u043e \u043d\u0435 \u043d\u0443\u0436\u0435\u043d. \u041f\u0430\u0440\u0441\u0435\u0440 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u044c AkburaDocumentSyntax \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0431\u043b\u0435\u043d\u0434\u0435\u0440\u0430, \u043a\u0443\u0440\u0441\u043e\u0440 \u0441\u0440\u0430\u0437\u0443 \u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u043a \u043f\u0435\u0440\u0432\u043e\u043c\u0443 child:_oldTreeCursor = new Cursor(oldTree).MoveToFirstChild();MoveToFirstChildMoveToFirstChild \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0441\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u044c \u0442\u0435\u043a\u0443\u0449\u0435\u0439 node:public Cursor MoveToFirstChild(){    if (IsFinished || !_current.AsNode(out var node))    {        return MoveToNextSibling();    }    var children = node.ChildNodesAndTokens();    if (TryGetFirstNonZeroWidthChild(children, out var child, out var childIndex))    {        return new Cursor(            child,            new PathNode(_current, _parent, _indexInParent, children),            childIndex);    }    return MoveToNextSibling();}\u0417\u0434\u0435\u0441\u044c \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u0435\u0442\u0430\u043b\u0435\u0439.\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, cursor \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 red tree, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0443\u0434\u043e\u0431\u043d\u0435\u0435 \u0431\u0440\u0430\u0442\u044c \u0438\u043c\u0435\u043d\u043d\u043e \u043e\u0442 red nodes \u0438 \u0442\u043e\u043a\u0435\u043d\u043e\u0432. Green tree \u0445\u0440\u0430\u043d\u0438\u0442 \u0448\u0438\u0440\u0438\u043d\u0443, \u043d\u043e \u043d\u0435 \u0445\u0440\u0430\u043d\u0438\u0442 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0432 \u0444\u0430\u0439\u043b\u0435. \u0410 \u0431\u043b\u0435\u043d\u0434\u0435\u0440 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442 \u0441\u0442\u0430\u0440\u044b\u0435 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0441 \u043d\u043e\u0432\u044b\u043c\u0438.\u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, cursor \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442 zero-width children. \u0412 syntax tree \u0447\u0430\u0441\u0442\u043e \u0431\u044b\u0432\u0430\u044e\u0442 missing-\u0442\u043e\u043a\u0435\u043d\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0430\u0440\u0441\u0435\u0440 \u043e\u0436\u0438\u0434\u0430\u043b ;, \u043d\u0435 \u043d\u0430\u0448\u0451\u043b \u0435\u0433\u043e \u0438 \u0441\u043e\u0437\u0434\u0430\u043b missing semicolon-\u0442\u043e\u043a\u0435\u043d \u0448\u0438\u0440\u0438\u043d\u043e\u0439 0. \u0414\u043b\u044f \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430 \u044d\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e: \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u043e\u0439. \u0414\u043b\u044f \u043f\u043e\u0442\u043e\u043a\u0430 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0430\u043a\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u043c\u0435\u0448\u0430\u0442\u044c. \u041e\u043d\u0438 \u043d\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0442 \u043c\u0435\u0441\u0442\u0430 \u0432 \u0442\u0435\u043a\u0441\u0442\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 cursor \u0438\u0445 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442.\u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435  EndOfFileToken:private static bool IsNonZeroWidthOrIsEndOfFile(SyntaxNodeOrToken nodeOrToken){    var underlying = nodeOrToken.UnderlyingNode;    return underlying != null &amp;&amp;           (underlying.FullWidth &gt; 0 ||            underlying.Kind == SyntaxKind.EndOfFileToken);}EOF \u0442\u043e\u0436\u0435 zero-width, \u043d\u043e \u044d\u0442\u043e \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u0442\u043e\u043a\u0435\u043d \u043a\u043e\u043d\u0446\u0430 \u043f\u043e\u0442\u043e\u043a\u0430.MoveToNextSibling\u041a\u043e\u0433\u0434\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0443\u0437\u0435\u043b \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d, \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0441\u043e\u0441\u0435\u0434\u0443:public Cursor MoveToNextSibling(){    if (IsFinished)    {        return default;    }    var parent = _parent;    if (parent == null)    {        return default;    }    if (TryGetNextNonZeroWidthChild(            parent.Children,            _indexInParent + 1,            out var sibling,            out var siblingIndex))    {        return new Cursor(sibling, parent, siblingIndex);    }    return MoveToParent().MoveToNextSibling();}\u0415\u0441\u043b\u0438 sibling \u0435\u0441\u0442\u044c, \u0432\u0441\u0451 \u043f\u0440\u043e\u0441\u0442\u043e. \u0415\u0441\u043b\u0438 sibling-\u0430 \u043d\u0435\u0442, cursor \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043a \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044e \u0438 \u0438\u0449\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0441\u043e\u0441\u0435\u0434\u0430 \u0443\u0436\u0435 \u0443 \u043d\u0435\u0433\u043e.\u0418\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u044d\u0442\u043e\u043c\u0443 cursor \u0445\u0440\u0430\u043d\u0438\u0442 PathNode:private sealed class PathNode{    public readonly SyntaxNodeOrToken NodeOrToken;    public readonly PathNode? Parent;    public readonly int IndexInParent;    public readonly ChildSyntaxList Children;}\u042d\u0442\u043e \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u0441\u0442\u0435\u043a \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u0435\u0439. \u041e\u043d \u043d\u0443\u0436\u0435\u043d, \u0447\u0442\u043e\u0431\u044b \u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f \u043f\u043e \u0434\u0435\u0440\u0435\u0432\u0443 \u0431\u0435\u0437 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e\u0433\u043e \u043e\u0431\u0445\u043e\u0434\u0447\u0438\u043a\u0430 \u0438 \u0431\u0435\u0437 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438 \u043e\u0442 root.MoveToParent\u0418\u043d\u043e\u0433\u0434\u0430 \u0431\u043b\u0435\u043d\u0434\u0435\u0440 \u0441\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0433\u043b\u0443\u0431\u043e\u043a\u043e \u0438 \u043f\u043e\u0442\u043e\u043c \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u0434\u043d\u044f\u0442\u044c\u0441\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u0433\u0434\u0430 \u043e\u043d \u0438\u0441\u043a\u0430\u043b \u043f\u0435\u0440\u0432\u044b\u0439 \u0442\u043e\u043a\u0435\u043d \u0432\u043d\u0443\u0442\u0440\u0438 node \u0438\u043b\u0438 \u043a\u043e\u0433\u0434\u0430 MoveToReusableNode \u0445\u043e\u0447\u0435\u0442 \u043d\u0430\u0439\u0442\u0438 \u0441\u0430\u043c\u044b\u0439 \u043a\u0440\u0443\u043f\u043d\u044b\u0439 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439 \u0443\u0437\u0435\u043b.public Cursor MoveToParent(){    if (IsFinished)    {        return default;    }    var parent = _parent;    if (parent == null)    {        return default;    }    return new Cursor(parent.NodeOrToken, parent.Parent, parent.IndexInParent);}\u0421\u0430\u043c\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0441\u0442\u0430\u044f, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u0443\u0442\u044c \u0443\u0436\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d.ReaderCursor \u0442\u043e\u043b\u044c\u043a\u043e \u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u0441\u0442\u0430\u0440\u043e\u043c\u0443 \u0434\u0435\u0440\u0435\u0432\u0443. \u0420\u0435\u0448\u0435\u043d\u0438\u0435, \u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0438\u043b\u0438 \u043d\u043e\u0432\u044b\u0439 \u043b\u0435\u043a\u0441\u0435\u0440, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 Blender.Reader.\u0412\u043d\u0435\u0448\u043d\u0438\u0439 Blender \u043f\u043e\u0447\u0442\u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 \u0441\u0430\u043c:public BlendedNode ReadNode(Lexer.LexerMode mode){    return&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-483191","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/483191","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=483191"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/483191\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=483191"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=483191"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=483191"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}