Diagnostika strukturovaného SARIF
Kompilátor MSVC lze provést pro výstupní diagnostiku jako SARIF (Static Analysis Results Interchange Format). SARIF je strojově čitelný formát JSON.
Kompilátor MSVC vytváří diagnostiku SARIF dvěma způsoby:
/experimental:log
Předejte přepínač na příkazovém řádku. Podrobnosti najdete v dokumentaci/experimental:log
.- Spusťte
cl.exe
programově a nastavteSARIF_OUTPUT_PIPE
proměnnou prostředí tak, aby načítala bloky SARIF přes kanál.
Načítání SARIF přes kanál
Nástroje, které využívají SARIF z kompilátoru MSVC, zatímco kompilace probíhá, používají kanál. Podrobnosti o vytváření kanálů Windows najdete v dokumentaci CreatePipe
.
Pokud chcete načíst SARIF přes kanál, nastavte SARIF_OUTPUT_PIPE
proměnnou prostředí na celočíselnou reprezentaci HANDLE
UTF-16 kódování na konec zápisu kanálu a pak spusťte cl.exe
. SARIF se odesílá podél potrubí následujícím způsobem:
- Pokud je k dispozici nová diagnostika, zapíše se do tohoto kanálu.
- Diagnostika se zapisuje do kanálu jednorázově, ne jako celý objekt SARIF.
- Každá diagnostika je reprezentována zprávou typu Oznámení typu JSON-RPC 2.0.
- Zpráva JSON-RPC má předponu
Content-Length
záhlaví s formulářemContent-Length: <N>
následovaným dvěma novými spojnicemi, kde<N>
je délka následující zprávy JSON-RPC v bajtech. - Zpráva JSON-RPC i hlavička jsou kódovány v kódování UTF-8.
- Tento formát JSON-RPC-with-header je kompatibilní s vs-streamjsonrpc.
- Název metody volání JSON-RPC je
OnSarifResult
. - Volání má jeden parametr, který je kódován podle názvu s názvem
result
parametru . - Hodnota argumentu je jeden
result
objekt určený standardem SARIF verze 2.1.
Příklad
Tady je příklad výsledku SARIF JSON-RPC vytvořeného:cl.exe
Content-Length: 334
{"jsonrpc":"2.0","method":"OnSarifResult","params":{"result":{"ruleId":"C1034","level":"fatal","message":{"text":"iostream: no include path set"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"file:///C:/Users/sybrand/source/repos/cppcon-diag/cppcon-diag/cppcon-diag.cpp"},"region":{"startLine":1,"startColumn":10}}}]}}}{"jsonrpc":"2.0","method":"OnSarifResult","params":{"result":{"ruleId":"C1034","level":"fatal","message":{"text":"iostream: no include path set"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"file:///C:/Users/sybrand/source/repos/cppcon-diag/cppcon-diag/cppcon-diag.cpp"},"region":{"startLine":1,"startColumn":10}}}]}}}
Data výsledků SARIF
Kompilátor vypíše SARIF, který může obsahovat další informace, které představují vnořenou strukturu některé diagnostiky. Diagnostika (reprezentovaná objektem result
SARIF) může obsahovat "diagnostický strom" dalších informací v jeho relatedLocations
poli. Tento strom je kódován pomocí tašky vlastností SARIF následujícím způsobem:
location
Pole objektu properties
může obsahovat nestingLevel
vlastnost, jejíž hodnota je hloubka tohoto umístění v diagnostickém stromu. Pokud umístění není nestingLevel
zadané, považuje se za hloubku 0
a toto umístění je podřízenou kořenovou diagnostikou reprezentovanou objektem, který result
ho obsahuje. Jinak platí, že pokud je hodnota větší než hloubka umístění bezprostředně před tímto umístěním v relatedLocations
poli, je toto umístění podřízeným umístěním. V opačném případě se jedná o stejné umístění, které odpovídá nejbližšímu předchozímu location
místu relatedLocations
v poli se stejnou hloubkou.
Příklad
Uvažujte následující kód:
struct dog {};
struct cat {};
void pet(dog);
void pet(cat);
struct lizard {};
int main() {
pet(lizard{});
}
Při kompilaci tohoto kódu kompilátor vytvoří následující result
objekt (physicalLocation
vlastnosti byly odebrány pro stručnost):
{
"ruleId": "C2665",
"level": "error",
"message": {
"text": "'pet': no overloaded function could convert all the argument types"
},
"relatedLocations": [
{
"id": 0,
"message": {
"text": "could be 'void pet(cat)'"
}
},
{
"id": 1,
"message": {
"text": "'void pet(cat)': cannot convert argument 1 from 'lizard' to 'cat'"
},
"properties": {
"nestingLevel": 1
}
},
{
"id": 2,
"message": {
"text": "No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called"
},
"properties": {
"nestingLevel": 2
}
},
{
"id": 3,
"message": {
"text": "or 'void pet(dog)'"
}
},
{
"id": 4,
"message": {
"text": "'void pet(dog)': cannot convert argument 1 from 'lizard' to 'dog'"
},
"properties": {
"nestingLevel": 1
}
},
{
"id": 5,
"message": {
"text": "No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called"
},
"properties": {
"nestingLevel": 2
}
},
{
"id": 6,
"message": {
"text": "while trying to match the argument list '(lizard)'"
}
}
]
}
Logický diagnostický strom vytvořený ze zpráv v tomto result
objektu je:
- Pet: Žádná přetížená funkce nemohla převést všechny typy argumentů.
- může být "void pet(kočka)"
- 'void pet(cat)': Nemůže převést argument 1 z 'ještěrky' na 'cat'.
- Není k dispozici žádný operátor převodu definovaný uživatelem, který by mohl provést tento převod, nebo nelze operátor volat.
- 'void pet(cat)': Nemůže převést argument 1 z 'ještěrky' na 'cat'.
- nebo "void pet(pes)"
- 'void pet(pes)': argument 1 nelze převést z 'ještěrky' na 'pes'
- Není k dispozici žádný operátor převodu definovaný uživatelem, který by mohl provést tento převod, nebo nelze operátor volat.
- 'void pet(pes)': argument 1 nelze převést z 'ještěrky' na 'pes'
- při pokusu o shodu se seznamem argumentů (ještěrka)
- může být "void pet(kočka)"
Viz také
/experimental:log
(Povolení strukturované diagnostiky SARIF)