yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Ellie HermaszewskaMove switch statement bodies to their own lines (#5493)b118451e3

master
4.6 KiB154 linesraw
1// slang-artifact-diagnostic-util.cpp
2#include "slang-artifact-diagnostic-util.h"
3
4#include "../core/slang-char-util.h"
5#include "../core/slang-string-util.h"
6
7namespace Slang
8{
9
10/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactDiagnosticsUtil !!!!!!!!!!!!!!!!!!!!!!!!!!! */
11
12/* static */ UnownedStringSlice ArtifactDiagnosticUtil::getSeverityText(Severity severity)
13{
14    switch (severity)
15    {
16    default:
17        return UnownedStringSlice::fromLiteral("Unknown");
18    case Severity::Info:
19        return UnownedStringSlice::fromLiteral("Info");
20    case Severity::Warning:
21        return UnownedStringSlice::fromLiteral("Warning");
22    case Severity::Error:
23        return UnownedStringSlice::fromLiteral("Error");
24    }
25}
26
27/* static */ SlangResult ArtifactDiagnosticUtil::splitPathLocation(
28    SliceAllocator& allocator,
29    const UnownedStringSlice& pathLocation,
30    ArtifactDiagnostic& outDiagnostic)
31{
32    const Index lineStartIndex = pathLocation.lastIndexOf('(');
33    if (lineStartIndex >= 0)
34    {
35        outDiagnostic.filePath = allocator.allocate(pathLocation.head(lineStartIndex).trim());
36
37        const UnownedStringSlice tail = pathLocation.tail(lineStartIndex + 1);
38        const Index lineEndIndex = tail.indexOf(')');
39
40        if (lineEndIndex >= 0)
41        {
42            // Extract the location info
43            UnownedStringSlice locationSlice(tail.begin(), tail.begin() + lineEndIndex);
44
45            UnownedStringSlice slices[2];
46            const Index numSlices = StringUtil::split(locationSlice, ',', 2, slices);
47
48            // NOTE! FXC actually outputs a range of columns in the form of START-END in the column
49            // position We don't need to parse here, because we only care about the line number
50
51            Int lineNumber = 0;
52            if (numSlices > 0)
53            {
54                SLANG_RETURN_ON_FAIL(StringUtil::parseInt(slices[0], lineNumber));
55            }
56
57            // Store the line
58            outDiagnostic.location.line = lineNumber;
59        }
60    }
61    else
62    {
63        outDiagnostic.filePath = allocator.allocate(pathLocation);
64    }
65    return SLANG_OK;
66}
67
68/* static */ SlangResult ArtifactDiagnosticUtil::splitColonDelimitedLine(
69    const UnownedStringSlice& line,
70    Int pathIndex,
71    List<UnownedStringSlice>& outSlices)
72{
73    StringUtil::split(line, ':', outSlices);
74
75    // Now we want to fix up a path as might have drive letter, and therefore :
76    // If this is the situation then we need to have a slice after the one at the index
77    if (outSlices.getCount() > pathIndex + 1)
78    {
79        const UnownedStringSlice pathStart = outSlices[pathIndex].trim();
80        if (pathStart.getLength() == 1 && CharUtil::isAlpha(pathStart[0]))
81        {
82            // Splice back together
83            outSlices[pathIndex] =
84                UnownedStringSlice(outSlices[pathIndex].begin(), outSlices[pathIndex + 1].end());
85            outSlices.removeAt(pathIndex + 1);
86        }
87    }
88
89    return SLANG_OK;
90}
91
92/* static */ SlangResult ArtifactDiagnosticUtil::parseColonDelimitedDiagnostics(
93    SliceAllocator& allocator,
94    const UnownedStringSlice& inText,
95    Int pathIndex,
96    LineParser lineParser,
97    IArtifactDiagnostics* diagnostics)
98{
99    List<UnownedStringSlice> splitLine;
100
101    UnownedStringSlice text(inText), line;
102    while (StringUtil::extractLine(text, line))
103    {
104        SLANG_RETURN_ON_FAIL(splitColonDelimitedLine(line, pathIndex, splitLine));
105
106        ArtifactDiagnostic diagnostic;
107        diagnostic.severity = Severity::Error;
108        diagnostic.stage = ArtifactDiagnostic::Stage::Compile;
109        diagnostic.location.line = 0;
110        diagnostic.location.column = 0;
111
112        if (SLANG_SUCCEEDED(lineParser(allocator, line, splitLine, diagnostic)))
113        {
114            diagnostics->add(diagnostic);
115        }
116        else
117        {
118            // If couldn't parse, just add as a note
119            maybeAddNote(line, diagnostics);
120        }
121    }
122
123    return SLANG_OK;
124}
125
126/* static */ void ArtifactDiagnosticUtil::maybeAddNote(
127    const UnownedStringSlice& in,
128    IArtifactDiagnostics* diagnostics)
129{
130    // Don't bother adding an empty line
131    if (in.trim().getLength() == 0)
132    {
133        return;
134    }
135
136    // If there's nothing previous, we'll ignore too, as note should be in addition to
137    // a pre-existing error/warning
138    if (diagnostics->getCount() == 0)
139    {
140        return;
141    }
142
143    // Make it a note on the output
144    ArtifactDiagnostic diagnostic;
145
146    String text(in);
147
148    diagnostic.severity = ArtifactDiagnostic::Severity::Info;
149    diagnostic.text = SliceUtil::asTerminatedCharSlice(text);
150    diagnostics->add(diagnostic);
151}
152
153
154} // namespace Slang