2727
2828namespace clang {
2929namespace clangd {
30+ namespace {
31+
32+ // Helper that doesn't treat `null` and absent fields as failures.
33+ template <typename T>
34+ bool mapOptOrNull (const llvm::json::Value &Params, llvm::StringLiteral Prop,
35+ T &Out, llvm::json::Path P) {
36+ auto *O = Params.getAsObject ();
37+ assert (O);
38+ auto *V = O->get (Prop);
39+ // Field is missing or null.
40+ if (!V || V->getAsNull ().hasValue ())
41+ return true ;
42+ return fromJSON (*V, Out, P.field (Prop));
43+ }
44+ } // namespace
3045
3146char LSPError::ID;
3247
@@ -490,7 +505,7 @@ bool fromJSON(const llvm::json::Value &Params, DidChangeTextDocumentParams &R,
490505 return O && O.map (" textDocument" , R.textDocument ) &&
491506 O.map (" contentChanges" , R.contentChanges ) &&
492507 O.map (" wantDiagnostics" , R.wantDiagnostics ) &&
493- O. mapOptional ( " forceRebuild" , R.forceRebuild );
508+ mapOptOrNull (Params, " forceRebuild" , R.forceRebuild , P );
494509}
495510
496511bool fromJSON (const llvm::json::Value &E, FileChangeType &Out,
@@ -580,10 +595,10 @@ bool fromJSON(const llvm::json::Value &Params, Diagnostic &R,
580595 llvm::json::Path P) {
581596 llvm::json::ObjectMapper O (Params, P);
582597 return O && O.map (" range" , R.range ) && O.map (" message" , R.message ) &&
583- O. mapOptional ( " severity" , R.severity ) &&
584- O. mapOptional ( " category" , R.category ) &&
585- O. mapOptional ( " code" , R.code ) && O. mapOptional ( " source " , R. source );
586- return true ;
598+ mapOptOrNull (Params, " severity" , R.severity , P ) &&
599+ mapOptOrNull (Params, " category" , R.category , P ) &&
600+ mapOptOrNull (Params, " code" , R.code , P ) &&
601+ mapOptOrNull (Params, " source " , R. source , P) ;
587602}
588603
589604llvm::json::Value toJSON (const PublishDiagnosticsParams &PDP) {
@@ -818,7 +833,7 @@ bool fromJSON(const llvm::json::Value &Params, CompletionContext &R,
818833 llvm::json::ObjectMapper O (Params, P);
819834 int TriggerKind;
820835 if (!O || !O.map (" triggerKind" , TriggerKind) ||
821- !O. mapOptional ( " triggerCharacter" , R.triggerCharacter ))
836+ !mapOptOrNull (Params, " triggerCharacter" , R.triggerCharacter , P ))
822837 return false ;
823838 R.triggerKind = static_cast <CompletionTriggerKind>(TriggerKind);
824839 return true ;
@@ -1121,8 +1136,8 @@ bool fromJSON(const llvm::json::Value &Params, ConfigurationSettings &S,
11211136 llvm::json::ObjectMapper O (Params, P);
11221137 if (!O)
11231138 return true ; // 'any' type in LSP.
1124- return O. mapOptional ( " compilationDatabaseChanges" ,
1125- S.compilationDatabaseChanges );
1139+ return mapOptOrNull (Params, " compilationDatabaseChanges" ,
1140+ S.compilationDatabaseChanges , P );
11261141}
11271142
11281143bool fromJSON (const llvm::json::Value &Params, InitializationOptions &Opts,
@@ -1133,8 +1148,8 @@ bool fromJSON(const llvm::json::Value &Params, InitializationOptions &Opts,
11331148
11341149 return fromJSON (Params, Opts.ConfigSettings , P) &&
11351150 O.map (" compilationDatabasePath" , Opts.compilationDatabasePath ) &&
1136- O. mapOptional ( " fallbackFlags" , Opts.fallbackFlags ) &&
1137- O. mapOptional ( " clangdFileStatus" , Opts.FileStatus );
1151+ mapOptOrNull (Params, " fallbackFlags" , Opts.fallbackFlags , P ) &&
1152+ mapOptOrNull (Params, " clangdFileStatus" , Opts.FileStatus , P );
11381153}
11391154
11401155bool fromJSON (const llvm::json::Value &E, TypeHierarchyDirection &Out,
@@ -1190,10 +1205,11 @@ bool fromJSON(const llvm::json::Value &Params, TypeHierarchyItem &I,
11901205 return O && O.map (" name" , I.name ) && O.map (" kind" , I.kind ) &&
11911206 O.map (" uri" , I.uri ) && O.map (" range" , I.range ) &&
11921207 O.map (" selectionRange" , I.selectionRange ) &&
1193- O.mapOptional (" detail" , I.detail ) &&
1194- O.mapOptional (" deprecated" , I.deprecated ) &&
1195- O.mapOptional (" parents" , I.parents ) &&
1196- O.mapOptional (" children" , I.children ) && O.mapOptional (" data" , I.data );
1208+ mapOptOrNull (Params, " detail" , I.detail , P) &&
1209+ mapOptOrNull (Params, " deprecated" , I.deprecated , P) &&
1210+ mapOptOrNull (Params, " parents" , I.parents , P) &&
1211+ mapOptOrNull (Params, " children" , I.children , P) &&
1212+ mapOptOrNull (Params, " data" , I.data , P);
11971213}
11981214
11991215bool fromJSON (const llvm::json::Value &Params,
@@ -1238,7 +1254,7 @@ bool fromJSON(const llvm::json::Value &Params, CallHierarchyItem &I,
12381254 return O && O.map (" name" , I.name ) && O.map (" kind" , I.kind ) &&
12391255 O.map (" uri" , I.uri ) && O.map (" range" , I.range ) &&
12401256 O.map (" selectionRange" , I.selectionRange ) &&
1241- O. mapOptional ( " data" , I.data );
1257+ mapOptOrNull (Params, " data" , I.data , P );
12421258}
12431259
12441260bool fromJSON (const llvm::json::Value &Params,
0 commit comments