// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. // This file is ported and adapted from ComputeSharp (Sergio0694/ComputeSharp), // more info in ThirdPartyNotices.txt in the root of the project. using System.Collections.Immutable; using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; namespace CommunityToolkit.Mvvm.SourceGenerators.Models; /// partial record HierarchyInfo { /// /// Creates a instance wrapping the given members. /// /// The input instances to use. /// The optional instance to add to generated types. /// A object wrapping . public CompilationUnitSyntax GetCompilationUnit( ImmutableArray memberDeclarations, BaseListSyntax? baseList = null) { // Create the partial type declaration with the given member declarations. // This code produces a class declaration as follows: // // partial TYPE_NAME> // { // // } TypeDeclarationSyntax typeDeclarationSyntax = Hierarchy[0].GetSyntax() .AddModifiers(Token(SyntaxKind.PartialKeyword)) .AddMembers(memberDeclarations.ToArray()); // Add the base list, if present if (baseList is not null) { typeDeclarationSyntax = typeDeclarationSyntax.WithBaseList(baseList); } // Add all parent types in ascending order, if any foreach (TypeInfo parentType in Hierarchy.AsSpan().Slice(1)) { typeDeclarationSyntax = parentType.GetSyntax() .AddModifiers(Token(SyntaxKind.PartialKeyword)) .AddMembers(typeDeclarationSyntax); } // Prepare the leading trivia for the generated compilation unit. // This will produce code as follows: // // // #pragma warning disable // #nullable enable SyntaxTriviaList syntaxTriviaList = TriviaList( Comment("// "), Trivia(PragmaWarningDirectiveTrivia(Token(SyntaxKind.DisableKeyword), true)), Trivia(NullableDirectiveTrivia(Token(SyntaxKind.EnableKeyword), true))); if (Namespace is "") { // If there is no namespace, attach the pragma directly to the declared type, // and skip the namespace declaration. This will produce code as follows: // // // return CompilationUnit() .AddMembers(typeDeclarationSyntax.WithLeadingTrivia(syntaxTriviaList)) .NormalizeWhitespace(); } // Create the compilation unit with disabled warnings, target namespace and generated type. // This will produce code as follows: // // // namespace // { // // } return CompilationUnit().AddMembers( NamespaceDeclaration(IdentifierName(Namespace)) .WithLeadingTrivia(syntaxTriviaList) .AddMembers(typeDeclarationSyntax)) .NormalizeWhitespace(); } }