@@ -139,6 +139,9 @@ parseSymbolFilter(
139
139
root.mergePattern (parts, excluded);
140
140
}
141
141
142
+ dom::Object
143
+ toDomObject (std::string_view configYaml);
144
+
142
145
} // (anon)
143
146
144
147
ConfigImpl::
@@ -174,6 +177,7 @@ ConfigImpl(
174
177
// Config strings
175
178
settings_.configYaml = configYaml;
176
179
settings_.extraYaml = extraYaml;
180
+ configObj_ = toDomObject (settings_.configYaml );
177
181
178
182
// Parse the YAML strings
179
183
YamlReporter reporter;
@@ -338,5 +342,142 @@ loadConfigFile(
338
342
threadPool);
339
343
}
340
344
345
+ namespace {
346
+ dom::Value
347
+ toDom (llvm::yaml::Node* Value);
348
+
349
+ dom::Object
350
+ toDomObject (llvm::yaml::MappingNode* Object)
351
+ {
352
+ dom::Object obj;
353
+ for (auto &Pair : *Object)
354
+ {
355
+ auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(Pair.getKey ());
356
+ if (!KeyString) { continue ; }
357
+ SmallString<10 > KeyStorage;
358
+ StringRef KeyValue = KeyString->getValue (KeyStorage);
359
+ llvm::yaml::Node *Value = Pair.getValue ();
360
+ if (!Value) {
361
+ obj.set (KeyValue, dom::Kind::Undefined);
362
+ continue ;
363
+ }
364
+ dom::Value value = toDom (Value);
365
+ obj.set (KeyValue, value);
366
+ }
367
+ return obj;
368
+ }
369
+
370
+ dom::Array
371
+ toDomArray (llvm::yaml::SequenceNode* Array)
372
+ {
373
+ dom::Array arr;
374
+ for (auto &Node : *Array)
375
+ {
376
+ dom::Value value = toDom (&Node);
377
+ arr.push_back (value);
378
+ }
379
+ return arr;
380
+ }
381
+
382
+ dom::Value
383
+ toDomScalar (llvm::yaml::ScalarNode* Scalar)
384
+ {
385
+ SmallString<10 > ScalarStorage;
386
+ StringRef ScalarValue = Scalar->getValue (ScalarStorage);
387
+ StringRef RawValue = Scalar->getRawValue ();
388
+ bool const isEscaped = RawValue.size () != ScalarValue.size ();
389
+ if (isEscaped)
390
+ {
391
+ return ScalarValue;
392
+ }
393
+ std::int64_t integer;
394
+ auto res = std::from_chars (
395
+ ScalarValue.begin (),
396
+ ScalarValue.end (),
397
+ integer);
398
+ if (res.ec == std::errc ())
399
+ {
400
+ return integer;
401
+ }
402
+ bool const isBool = ScalarValue == " true" || ScalarValue == " false" ;
403
+ if (isBool)
404
+ {
405
+ return ScalarValue == " true" ;
406
+ }
407
+ bool const isNull = ScalarValue == " null" ;
408
+ if (isNull)
409
+ {
410
+ return nullptr ;
411
+ }
412
+ return ScalarValue;
413
+ }
414
+
415
+ dom::Value
416
+ toDom (llvm::yaml::Node* Value)
417
+ {
418
+ auto *ValueObject = dyn_cast<llvm::yaml::MappingNode>(Value);
419
+ if (ValueObject)
420
+ {
421
+ return toDomObject (ValueObject);
422
+ }
423
+ auto *ValueArray = dyn_cast<llvm::yaml::SequenceNode>(Value);
424
+ if (ValueArray)
425
+ {
426
+ return toDomArray (ValueArray);
427
+ }
428
+ auto *ValueString = dyn_cast<llvm::yaml::ScalarNode>(Value);
429
+ if (ValueString)
430
+ {
431
+ return toDomScalar (ValueString);
432
+ }
433
+ return nullptr ;
434
+ }
435
+
436
+ /* Convert a YAML string to a DOM object.
437
+
438
+ YAML forbids tab characters to use as indentation so
439
+ only some JSON files are valid YAML.
440
+
441
+ Also instead of providing built-in support for
442
+ types such as `bool` or `int`, YAML uses strings
443
+ for everything, which the specification defines
444
+ as "scalar" values.
445
+
446
+ When converting a scalar to a DOM value, only
447
+ escaped strings are preserved as strings.
448
+ Unescaped strings are converted to numbers
449
+ if possible, and then to booleans if possible.
450
+ This is done to preserve compatibility with
451
+ JSON, allow the user to specify scalars as
452
+ boolean or integer values, match the original
453
+ intent of the author, and for scalar values
454
+ to interoperate with other handlebars templates.
455
+
456
+ */
457
+ dom::Object
458
+ toDomObject (std::string_view yaml)
459
+ {
460
+ llvm::SourceMgr SM;
461
+ llvm::yaml::Stream YAMLStream_ (yaml, SM);
462
+ llvm::yaml::document_iterator I = YAMLStream_.begin ();
463
+ if (I == YAMLStream_.end ())
464
+ {
465
+ return {};
466
+ }
467
+ llvm::yaml::Node *Root = I->getRoot ();
468
+ auto *Object = dyn_cast<llvm::yaml::MappingNode>(Root);
469
+ if (!Object)
470
+ {
471
+ return {};
472
+ }
473
+ return toDomObject (Object);
474
+ }
475
+ } // (anon)
476
+
477
+ dom::Object const &
478
+ ConfigImpl::object () const {
479
+ return configObj_;
480
+ }
481
+
341
482
} // mrdocs
342
483
} // clang
0 commit comments