Exemple #1
0
        /// <summary>
        /// Gets the sequence of processed discovered custom types.
        /// </summary>
        /// <param name="diagnostics">The collection of produced <see cref="Diagnostic"/> instances.</param>
        /// <param name="structDeclarationSymbol">The type symbol for the shader type.</param>
        /// <param name="types">The sequence of discovered custom types.</param>
        /// <returns>A sequence of custom type definitions to add to the shader source.</returns>
        private static ImmutableArray <(string Name, string Definition)> GetDeclaredTypes(
            ImmutableArray <Diagnostic> .Builder diagnostics,
            INamedTypeSymbol structDeclarationSymbol,
            IEnumerable <INamedTypeSymbol> types)
        {
            ImmutableArray <(string, string)> .Builder builder = ImmutableArray.CreateBuilder <(string, string)>();
            IReadOnlyCollection <INamedTypeSymbol>     invalidTypes;

            // Process the discovered types
            foreach (var type in HlslKnownTypes.GetCustomTypes(types, out invalidTypes))
            {
                var structType        = type.GetFullMetadataName().ToHlslIdentifierName();
                var structDeclaration = StructDeclaration(structType);

                // Declare the fields of the current type
                foreach (var field in type.GetMembers().OfType <IFieldSymbol>())
                {
                    if (field.IsStatic)
                    {
                        continue;
                    }

                    INamedTypeSymbol fieldType = (INamedTypeSymbol)field.Type;

                    // Convert the name to the fully qualified HLSL version
                    if (!HlslKnownTypes.TryGetMappedName(fieldType.GetFullMetadataName(), out string?mappedType))
                    {
                        mappedType = fieldType.GetFullMetadataName().ToHlslIdentifierName();
                    }

                    // Get the field name as a valid HLSL identifier
                    if (!HlslKnownKeywords.TryGetMappedName(field.Name, out string?mappedName))
                    {
                        mappedName = field.Name;
                    }

                    structDeclaration = structDeclaration.AddMembers(
                        FieldDeclaration(VariableDeclaration(
                                             IdentifierName(mappedType !)).AddVariables(
                                             VariableDeclarator(Identifier(mappedName !)))));
                }

                // Insert the trailing ; right after the closing bracket (after normalization)
                builder.Add((
                                structType,
                                structDeclaration
                                .NormalizeWhitespace(eol: "\n")
                                .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
                                .ToFullString()));
            }

            // Process the invalid types
            foreach (INamedTypeSymbol invalidType in invalidTypes)
            {
                diagnostics.Add(InvalidDiscoveredType, structDeclarationSymbol, structDeclarationSymbol, invalidType);
            }

            return(builder.ToImmutable());
        }
        public static TypeSyntax TrackType(this SyntaxNode node, SemanticModel semanticModel, ICollection <INamedTypeSymbol> discoveredTypes)
        {
            ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(node).Type !;
            string      typeName   = typeSymbol.ToDisplayString(ISymbolExtensions.FullyQualifiedWithoutGlobalFormat);

            discoveredTypes.Add((INamedTypeSymbol)typeSymbol);

            if (HlslKnownTypes.TryGetMappedName(typeName, out string?mappedName))
            {
                return(ParseTypeName(mappedName !));
            }

            return(ParseTypeName(typeName.Replace(".", "__")));
        }
Exemple #3
0
    /// <summary>
    /// Tracks the associated type for a <see cref="SyntaxNode"/> value and returns the HLSL compatible <see cref="TypeSyntax"/>.
    /// </summary>
    /// <param name="node">The input <see cref="SyntaxNode"/> to check.</param>
    /// <param name="semanticModel">The <see cref="SemanticModel"/> instance with info on the input tree.</param>
    /// <param name="discoveredTypes">The collection of currently discovered types.</param>
    /// <returns>A <see cref="SyntaxNode"/> instance that represents a type compatible with HLSL.</returns>
    public static TypeSyntax TrackType(this SyntaxNode node, SemanticModel semanticModel, ICollection <INamedTypeSymbol> discoveredTypes)
    {
        ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(node).Type !;
        string      typeName   = typeSymbol.GetFullyQualifiedName();

        discoveredTypes.Add((INamedTypeSymbol)typeSymbol);

        if (HlslKnownTypes.TryGetMappedName(typeName, out string?mappedName))
        {
            return(ParseTypeName(mappedName !));
        }

        return(ParseTypeName(typeName.ToHlslIdentifierName()));
    }
        public static TRoot ReplaceAndTrackType <TRoot>(this TRoot node, TypeSyntax targetType, SyntaxNode sourceType, SemanticModel semanticModel, ICollection <INamedTypeSymbol> discoveredTypes)
            where TRoot : SyntaxNode
        {
            // Skip immediately for function pointers
            if (sourceType is FunctionPointerTypeSyntax)
            {
                return(node.ReplaceNode(targetType, ParseTypeName("void*")));
            }

            // Handle the various possible type kinds
            ITypeSymbol typeSymbol = sourceType switch
            {
                RefTypeSyntax refType => semanticModel.GetTypeInfo(refType.Type).Type !,
                PointerTypeSyntax pointerType => semanticModel.GetTypeInfo(pointerType.ElementType).Type !,
                _ => semanticModel.GetTypeInfo(sourceType).Type !
            };

            // Do nothing if the type is just void
            if (typeSymbol.SpecialType == SpecialType.System_Void)
            {
                return(node);
            }

            string typeName = typeSymbol.ToDisplayString(ISymbolExtensions.FullyQualifiedWithoutGlobalFormat);

            discoveredTypes.Add((INamedTypeSymbol)typeSymbol);

            if (HlslKnownTypes.TryGetMappedName(typeName, out string?mappedName))
            {
                TypeSyntax newType = ParseTypeName(mappedName !);

                return(node.ReplaceNode(targetType, newType));
            }

            return(node.ReplaceNode(targetType, ParseTypeName(typeName.Replace(".", "__"))));
        }