Я пытаюсь создать инкрементальный генератор исходного кода, который генерирует конструкторы C# для внедрения зависимостей. Однако, похоже, мой генератор создает 2 источника с одинаковым именем Classes.g.cs.
Проект размещен здесь. Чтобы попробовать:
git clone https://github.com/MintPlayer/MintPlayer.Dotnet.Tools
Запустите Visual Studio, установите проект SourceGenerators (НЕ SourceGenerators.Debug) в качестве запускаемого проекта и нажмите F5. Если у вас установлен .NET Compiler Platform SDK с помощью установщика Visual Studio, генераторы будут запущены в файлах проекта отладки.
Вы вижу, что оператор точки останова, который я добавил в код, выполняется дважды, поэтому генератор создает этот файл один раз слишком часто.
Почему этот генератор запускается дважды?
Справочная информация
Классы XxxSourceGenerator являются настоящими генераторами. Они будут запускаться Visual Studio, пока вы вводите код.
[Generator(LanguageNames.CSharp)]
public class ClassNamesSourceGenerator : IIncrementalGenerator {
public void Initialize(IncrementalGeneratorInitializationContext context) {
var classDeclarationsProvider = context.SyntaxProvider
.CreateSyntaxProvider(
static (node, ct) => node is ClassDeclarationSyntax { } classDeclaration,
static (context, ct) => {
if (context.Node is ClassDeclarationSyntax classDeclaration &&
context.SemanticModel.GetDeclaredSymbol(classDeclaration, ct) is INamedTypeSymbol symbol) {
return new Models.ClassDeclaration { Name = symbol.Name };
} else {
return default;
}
}
)
.WithComparer(ValueComparers.ClassDeclarationValueComparer.Instance)
.Collect();
var fieldDeclarationsProvider = context.SyntaxProvider
.CreateSyntaxProvider(
static (node, ct) => node is FieldDeclarationSyntax { AttributeLists.Count: > 0 } fieldDeclaration
&& fieldDeclaration.Modifiers.Any(Microsoft.CodeAnalysis.CSharp.SyntaxKind.ReadOnlyKeyword),
static (context2, ct) => {
...
return new Models.FieldDeclaration {
Namespace = namespaceDeclaration.Name.ToString(),
FullyQualifiedClassName = classSymbol.ToDisplayString(),
ClassName = classSymbol.Name,
Name = symbol.Name,
FullyQualifiedTypeName = symbol.Type.ToDisplayString(),
Type = symbol.Type.Name,
};
}
)
.Collect();
Сначала они преобразуют данные от поставщиков и, в свою очередь, обращаются к нескольким производителям, которые индивидуально преобразуют символы в код C#.
var classNamesSourceProvider = classDeclarationsProvider
.Combine(config)
.Select(static (p, ct) => new Producers.ClassNamesProducer(declarations: p.Left, rootNamespace: p.Right.RootNamespace!));
var classNameListSourceProvider = classDeclarationsProvider
.Combine(config)
.Select(static (p, ct) => new Producers.ClassNameListProducer(declarations: p.Left, rootNamespace: p.Right.RootNamespace!));
var fieldDeclarationSourceProvider = fieldDeclarationsProvider
.Combine(config)
.Select(static (p, ct) => new Producers.FieldNameListProducer(declarations: p.Left, rootNamespace: p.Right.RootNamespace!));
Затем вам нужно объединить выходные данные всех этих производителей и передать поставщика исходного кода в .NET/VS
// Combine all Source Providers
var sourceProvider = classNamesSourceProvider
.Combine(classNameListSourceProvider)
.SelectMany(static (p, _) => new Producer[] { p.Left, p.Right })
.Combine(fieldDeclarationSourceProvider)
.SelectMany(static (p, _) => new Producer[] { p.Left, p.Right });
// Generate Code
context.RegisterSourceOutput(sourceProvider, static (c, g) => g?.Produce(c));
Подробнее здесь: https://stackoverflow.com/questions/790 ... e-filename
Инкрементный генератор создает дубликаты имен файлов ⇐ C#
Место общения программистов C#
-
Anonymous
1727529460
Anonymous
Я пытаюсь создать инкрементальный генератор исходного кода, который генерирует конструкторы C# для внедрения зависимостей. Однако, похоже, мой генератор создает 2 источника с одинаковым именем Classes.g.cs.
Проект размещен здесь. Чтобы попробовать:
git clone https://github.com/MintPlayer/MintPlayer.Dotnet.Tools
Запустите Visual Studio, установите проект [b]SourceGenerators[/b] (НЕ SourceGenerators.Debug) в качестве запускаемого проекта и нажмите F5. Если у вас установлен [b].NET Compiler Platform SDK[/b] с помощью установщика Visual Studio, генераторы будут запущены в файлах проекта отладки.
Вы вижу, что оператор точки останова, который я добавил в код, выполняется дважды, поэтому генератор создает этот файл один раз слишком часто.
Почему этот генератор запускается дважды?
Справочная информация
Классы XxxSourceGenerator являются настоящими генераторами. Они будут запускаться Visual Studio, пока вы вводите код.
[Generator(LanguageNames.CSharp)]
public class ClassNamesSourceGenerator : IIncrementalGenerator {
public void Initialize(IncrementalGeneratorInitializationContext context) {
var classDeclarationsProvider = context.SyntaxProvider
.CreateSyntaxProvider(
static (node, ct) => node is ClassDeclarationSyntax { } classDeclaration,
static (context, ct) => {
if (context.Node is ClassDeclarationSyntax classDeclaration &&
context.SemanticModel.GetDeclaredSymbol(classDeclaration, ct) is INamedTypeSymbol symbol) {
return new Models.ClassDeclaration { Name = symbol.Name };
} else {
return default;
}
}
)
.WithComparer(ValueComparers.ClassDeclarationValueComparer.Instance)
.Collect();
var fieldDeclarationsProvider = context.SyntaxProvider
.CreateSyntaxProvider(
static (node, ct) => node is FieldDeclarationSyntax { AttributeLists.Count: > 0 } fieldDeclaration
&& fieldDeclaration.Modifiers.Any(Microsoft.CodeAnalysis.CSharp.SyntaxKind.ReadOnlyKeyword),
static (context2, ct) => {
...
return new Models.FieldDeclaration {
Namespace = namespaceDeclaration.Name.ToString(),
FullyQualifiedClassName = classSymbol.ToDisplayString(),
ClassName = classSymbol.Name,
Name = symbol.Name,
FullyQualifiedTypeName = symbol.Type.ToDisplayString(),
Type = symbol.Type.Name,
};
}
)
.Collect();
Сначала они преобразуют данные от поставщиков и, в свою очередь, обращаются к нескольким производителям, которые индивидуально преобразуют символы в код C#.
var classNamesSourceProvider = classDeclarationsProvider
.Combine(config)
.Select(static (p, ct) => new Producers.ClassNamesProducer(declarations: p.Left, rootNamespace: p.Right.RootNamespace!));
var classNameListSourceProvider = classDeclarationsProvider
.Combine(config)
.Select(static (p, ct) => new Producers.ClassNameListProducer(declarations: p.Left, rootNamespace: p.Right.RootNamespace!));
var fieldDeclarationSourceProvider = fieldDeclarationsProvider
.Combine(config)
.Select(static (p, ct) => new Producers.FieldNameListProducer(declarations: p.Left, rootNamespace: p.Right.RootNamespace!));
Затем вам нужно объединить выходные данные всех этих производителей и передать поставщика исходного кода в .NET/VS
// Combine all Source Providers
var sourceProvider = classNamesSourceProvider
.Combine(classNameListSourceProvider)
.SelectMany(static (p, _) => new Producer[] { p.Left, p.Right })
.Combine(fieldDeclarationSourceProvider)
.SelectMany(static (p, _) => new Producer[] { p.Left, p.Right });
// Generate Code
context.RegisterSourceOutput(sourceProvider, static (c, g) => g?.Produce(c));
Подробнее здесь: [url]https://stackoverflow.com/questions/79034293/incremental-generator-produces-duplicate-filename[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия