/// <summary> /// Gets a sequence of shader static fields and their mapped names. /// </summary> /// <param name="diagnostics">The collection of produced <see cref="Diagnostic"/> instances.</param> /// <param name="semanticModel">The <see cref="SemanticModelProvider"/> instance for the type to process.</param> /// <param name="structDeclaration">The <see cref="StructDeclarationSyntax"/> instance for the current type.</param> /// <param name="structDeclarationSymbol">The type symbol for the shader type.</param> /// <param name="discoveredTypes">The collection of currently discovered types.</param> /// <param name="constantDefinitions">The collection of discovered constant definitions.</param> /// <returns>A sequence of static constant fields in <paramref name="structDeclarationSymbol"/>.</returns> private static ImmutableArray <(string Name, string TypeDeclaration, string?Assignment)> GetStaticFields( ImmutableArray <Diagnostic> .Builder diagnostics, SemanticModelProvider semanticModel, StructDeclarationSyntax structDeclaration, INamedTypeSymbol structDeclarationSymbol, ICollection <INamedTypeSymbol> discoveredTypes, IDictionary <IFieldSymbol, string> constantDefinitions) { ImmutableArray <(string, string, string?)> .Builder builder = ImmutableArray.CreateBuilder <(string, string, string?)>(); foreach (var fieldDeclaration in structDeclaration.Members.OfType <FieldDeclarationSyntax>()) { foreach (var variableDeclarator in fieldDeclaration.Declaration.Variables) { IFieldSymbol fieldSymbol = (IFieldSymbol)semanticModel.For(variableDeclarator).GetDeclaredSymbol(variableDeclarator) !; if (!fieldSymbol.IsStatic || fieldSymbol.IsConst) { continue; } // Constant properties must be of a primitive, vector or matrix type if (fieldSymbol.Type is not INamedTypeSymbol typeSymbol || !HlslKnownTypes.IsKnownHlslType(typeSymbol.GetFullMetadataName())) { diagnostics.Add(InvalidShaderStaticFieldType, variableDeclarator, structDeclarationSymbol, fieldSymbol.Name, fieldSymbol.Type); continue; } _ = HlslKnownKeywords.TryGetMappedName(fieldSymbol.Name, out string?mapping); string typeDeclaration = fieldSymbol.IsReadOnly switch { true => $"static const {HlslKnownTypes.GetMappedName(typeSymbol)}", false => $"static {HlslKnownTypes.GetMappedName(typeSymbol)}" }; StaticFieldRewriter staticFieldRewriter = new( semanticModel, discoveredTypes, constantDefinitions, diagnostics); string?assignment = staticFieldRewriter.Visit(variableDeclarator)?.NormalizeWhitespace(eol: "\n").ToFullString(); builder.Add((mapping ?? fieldSymbol.Name, typeDeclaration, assignment)); } } return(builder.ToImmutable()); }
/// <summary> /// Gets a sequence of captured fields and their mapped names. /// </summary> /// <param name="diagnostics">The collection of produced <see cref="Diagnostic"/> instances.</param> /// <param name="structDeclarationSymbol">The input <see cref="INamedTypeSymbol"/> instance to process.</param> /// <param name="types">The collection of currently discovered types.</param> /// <returns>A sequence of captured fields in <paramref name="structDeclarationSymbol"/>.</returns> private static ImmutableArray <(string Name, string HlslType)> GetInstanceFields( ImmutableArray <Diagnostic> .Builder diagnostics, INamedTypeSymbol structDeclarationSymbol, ICollection <INamedTypeSymbol> types) { ImmutableArray <(string, string)> .Builder values = ImmutableArray.CreateBuilder <(string, string)>(); foreach (var fieldSymbol in structDeclarationSymbol.GetMembers().OfType <IFieldSymbol>()) { if (fieldSymbol.IsStatic) { continue; } // Captured fields must be named type symbols if (fieldSymbol.Type is not INamedTypeSymbol typeSymbol) { diagnostics.Add(InvalidShaderField, fieldSymbol, structDeclarationSymbol, fieldSymbol.Name, fieldSymbol.Type); continue; } string metadataName = typeSymbol.GetFullMetadataName(); string typeName = HlslKnownTypes.GetMappedName(typeSymbol); _ = HlslKnownKeywords.TryGetMappedName(fieldSymbol.Name, out string?mapping); // Allowed fields must be unmanaged values if (typeSymbol.IsUnmanagedType) { // Track the type if it's a custom struct if (!HlslKnownTypes.IsKnownHlslType(metadataName)) { types.Add(typeSymbol); } values.Add((mapping ?? fieldSymbol.Name, typeName)); } else { diagnostics.Add(InvalidShaderField, fieldSymbol, structDeclarationSymbol, fieldSymbol.Name, typeSymbol); } } return(values.ToImmutable()); }