Diagnostica SARIF strutturata
Il compilatore MSVC può essere eseguito per restituire la diagnostica come SARIF (Static Analysis Results Interchange Format). SARIF è un formato basato su JSON leggibile dal computer.
Esistono due modi per fare in modo che il compilatore MSVC produca diagnostica SARIF:
- Passare l'opzione
/experimental:log
sulla riga di comando. Per informazioni dettagliate, vedere la documentazione/experimental:log
. - Avviare
cl.exe
a livello di codice e impostare laSARIF_OUTPUT_PIPE
variabile di ambiente per recuperare i blocchi SARIF attraverso una pipe.
Recupero di SARIF tramite una pipe
Gli strumenti che utilizzano SARIF dal compilatore MSVC mentre è in corso una compilazione usano una pipe. Per informazioni dettagliate sulla creazione di pipe di Windows, vedere la documentazione CreatePipe
.
Per recuperare SARIF tramite una pipe, impostare la SARIF_OUTPUT_PIPE
variabile di ambiente come rappresentazione integer con codifica UTF-16 dell'oggetto HANDLE
alla fine di scrittura della pipe, quindi avviare cl.exe
. SARIF viene inviato lungo la pipe come indicato di seguito:
- Quando è disponibile una nuova diagnostica, viene scritta in questa pipe.
- La diagnostica viene scritta nella pipe una alla volta anziché come intero oggetto SARIF.
- Ogni diagnostica è rappresentata da un messaggio JSON-RPC 2.0 di tipo Notification.
- Il messaggio JSON-RPC è preceduto da un'intestazione
Content-Length
con il formatoContent-Length: <N>
seguito da due nuove righe, dove<N>
è la lunghezza del seguente messaggio JSON-RPC in byte. - Il messaggio e l'intestazione JSON-RPC sono entrambi codificati in UTF-8.
- Questo formato JSON-RPC-with-header è compatibile con vs-streamjsonrpc.
- Il nome del metodo per la chiamata JSON-RPC è
OnSarifResult
. - La chiamata ha un singolo parametro codificato in base al nome con il nome
result
del parametro . - Il valore dell'argomento è un singolo
result
oggetto specificato dallo standard SARIF Versione 2.1.
Esempio
Di seguito è riportato un esempio di risultato SARIF JSON-RPC prodotto da 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}}}]}}}
Dati dei risultati SARIF
Il compilatore restituisce SARIF che può includere informazioni aggiuntive per rappresentare la struttura annidata di alcuni dati di diagnostica. Una diagnostica (rappresentata da un result
oggetto SARIF) può contenere un "albero di diagnostica" di informazioni aggiuntive nel relativo relatedLocations
campo. Questo albero viene codificato usando un contenitore di proprietà SARIF come indicato di seguito:
Il campo di properties
un location
oggetto può contenere una nestingLevel
proprietà il cui valore è la profondità di questa posizione nell'albero di diagnostica. Se una posizione non ha un nestingLevel
oggetto specificato, la profondità viene considerata come 0
e questa posizione è un elemento figlio della diagnostica radice rappresentata dall'oggetto result
che lo contiene. In caso contrario, se il valore è maggiore della profondità della posizione immediatamente precedente a questa posizione nel relatedLocations
campo, questa posizione è un elemento figlio di tale posizione. In caso contrario, questa posizione è un elemento di pari livello del precedente più location
vicino nel relatedLocations
campo con la stessa profondità.
Esempio
Si consideri il seguente codice :
struct dog {};
struct cat {};
void pet(dog);
void pet(cat);
struct lizard {};
int main() {
pet(lizard{});
}
Quando questo codice viene compilato, il compilatore produce l'oggetto seguente result
(physicalLocation
le proprietà sono state rimosse per brevità):
{
"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)'"
}
}
]
}
L'albero di diagnostica logico prodotto dai messaggi in questo result
oggetto è:
- 'pet': nessuna funzione di overload potrebbe convertire tutti i tipi di argomento
- potrebbe essere 'void pet(cat)'
- 'void pet(cat)': impossibile convertire l'argomento 1 da 'lucertola' a 'cat
- Non è disponibile alcun operatore di conversione definito dall'utente che può eseguire questa conversione oppure non è possibile chiamare l'operatore
- 'void pet(cat)': impossibile convertire l'argomento 1 da 'lucertola' a 'cat
- o 'void pet(dog)'
- 'void pet(dog)': impossibile convertire l'argomento 1 da 'lucertola' a 'dog'
- Non è disponibile alcun operatore di conversione definito dall'utente che può eseguire questa conversione oppure non è possibile chiamare l'operatore
- 'void pet(dog)': impossibile convertire l'argomento 1 da 'lucertola' a 'dog'
- durante il tentativo di trovare la corrispondenza con l'elenco di argomenti '(lucertola)'
- potrebbe essere 'void pet(cat)'
Vedi anche
/experimental:log
(Abilitare la diagnostica SARIF strutturata)