Esharp LeMP #r "path" работает только с абсолютным путем в директиве compileTime - PullRequest
1 голос
/ 11 июля 2020

Я использую последнюю версию 2.8.1

Я безуспешно пробовал исходный код проекта и двоичные относительные пути. Вот код: https://github.com/dadhi/LempTest/blob/strong text9ce17d16a8d7c71fc475921e1414e5bc64d72f9d / LibWithEcs / ServiceRegistrations.ecs.include # L3

Кроме того, я не уверен, как передать каталог с помощью --set: key = value. Следует ли заключать ключ или значение в кавычки, избегая косой черты? И если мне удастся пройти, могу ли я #get (key) в разделе compileTime и как-то использовать его для #r?

Обновление - после игры с @ Qwert ie answer

Я создал простой файл Test.ecs для проверки вывода --set:key=value

compileTime 
{
    using C = System.Console;
    var a = #get(a);
    C.WriteLine(a);
}

Вот что я обнаружил:

  • lemp Test.ecs --set:a="c:" возвращает «Ошибка: ожидалась частица ( id, literal, {фигурные скобки} или (скобки)). "
  • lemp Test.ecs --set:a=@"c:" возвращает" c: "
  • lemp Test.ecs --set:a=@"c:\Code" возвращает то же самое" c: "
  • lemp Test.ecs --set:a=@"c:\\Code" снова возвращает тот же "c:"

и как минимум

  • lemp Test.ecs --set:a="""c:\\Code""" работает и выводит "c: \ Код "

Обновление - передача значения Path в Lemp из MSBuild Exe c target

Последней частью головоломки для меня была передача $(ProjectDir) в качестве значения set:key=value переключатель командной строки. Вот окончательное ( на самом деле нет, см. Обновление ниже ) решение:

    <Target Name="LempTransform" BeforeTargets="BeforeBuild">
        <PropertyGroup>
            <ProjectDirEscaped>$(ProjectDir.Replace('\', '___'))</ProjectDirEscaped>
        </PropertyGroup>
        <!-- <Message Text="Project with escaped slashes is $(ProjectDirEscaped)" Importance="high"/> -->
        <Exec WorkingDirectory="$(ProjectDir)" 
            Command="dotnet lemp %(EcsFile.Identity) --outext=.Generated.cs --set:ProjectDir=@&quot;$(ProjectDirEscaped)&quot;" />
    </Target>

Основная проблема заключалась в том, что даже использования @&quot$(ProjectDir)&quot; было недостаточно, потому что ProjectDir выводит путь с одинарные косые черты, например c:\foo\bar. Тогда нет возможности избежать их внутри строкового литерала. В итоге я заменил косые черты вручную на string.Replace, а затем заменил их обратно при работе с ключом в файле .ecs:

compileTime 
{
    ##reference(precompute(System.IO.Path.Combine(#get(ProjectDir).Replace("___", "\\"), @"..\AnotherLib\bin\Debug\netstandard2.0\AnotherLib.dll")));

    using AnotherLib;

    //...

Обновление - более простое решение, заменив обратную косую черту на прямую. sh на @ Qwert ie комментарий

Комментарий очень помог, поэтому мне не нужно Replace экранированное значение обратно в шаблон потребления.

Во-первых, я заменяю \ с / вместо ___, что по-прежнему сохраняет путь действительным для. NET BCL API:

    <PropertyGroup>
        <ProjectDirEscaped>$(ProjectDir.Replace('\', '/'))</ProjectDirEscaped>
    </PropertyGroup>

Следовательно, мне не нужно Replace при использовании путь в ##reference:

    ##reference(precompute(System.IO.Path.Combine(#get(ProjectDir), @"..\AnotherLib\bin\Debug\netstandard2.0\AnotherLib.dll")));

1 Ответ

1 голос
/ 11 июля 2020

Относительные пути в #r у меня работают в расширении Visual Studio. Путь должен быть относительно местоположения исходного файла.

Чтобы узнать входную папку, в которую файл «верит», напишите #get(#inputFolder); в верхней части файла и затем посмотрите на вывод LeMP. Если в выводе указано _numget(_numinputFolder), что-то пошло не так - переменная не установлена, но можно было бы установить ее значение в командной строке: --set:#inputFolder="C:\\Dev\\MyFolder".

После --set:, key=value будет анализируется как выражение присваивания , поэтому вам следует заключить значение в кавычки и заменить обратную косую черту на двойную обратную косую черту. (Синтаксис выражения: LES или текущий язык ввода, если есть - --inlang=ecs для Enhanced C#)

Вы можете использовать #get(key) внутри compileTime; однако директива #r анализируется очень глупо из-за очень глупого синтаксиса директивы (который отличается от обычных строк C#). В результате макросы нельзя использовать в строке #r. Вероятно, вам не нужно обходить это ограничение, но если вы это сделаете, вы можете заменить #r "dir\Foo.dll" его эквивалентом Loy c tree ##reference(@"""dir\\Foo.dll"""); (дополнительные кавычки не являются обязательными), а затем вы можно использовать макросы в измененной строке.

Мне не приходило в голову, что можно использовать precompute внутри compileTime, но можно, и это работает. Так, например, вы можете сделать ##reference(precompute(System.IO.Path.Combine(@"dir", "Foo.dll")));.

...