Skip to content
Denis Kuzmin (github/3F) edited this page May 1, 2024 · 1 revision

About skeleton and map

When loading .sln file, MvsSln's parser can also co-generate the map of the analyzed data if the corresponding option is activated.

Each parsed line in this map represents a section containing the handler that processed that line and/or raw access through wrapper. For example:

Note the following,

  • Everything from this set can be overridden using any custom handlers (aka readers, ~ ISlnHandler)

  • This map, in turn, can be used for modifications using any other custom handlers (aka writers, ~ IObjHandler). For example, updating solution configurations:

Dictionary<Type, HandlerValue> whandlers = new()
{
    [typeof(LSolutionConfigurationPlatforms)] = new(new WSolutionConfigurationPlatforms(data)),
};

// use LSolutionConfigurationPlatforms = WSolutionConfigurationPlatforms
using SlnWriter w = new(whandlers);
await w.WriteAsStringAsync(sln.Result.Map); // reuse generated sln.Result.Map

Creating new map

If the map does not exist, for example .sln is created from scratch, then you also need to create it manually.

Modern 2.7+ provides SMap wrapper in order to control sections easily so it's all very simple like:

map.Add
(
    SMap.AddType.Before,
    typeof(LExtensibilityGlobals),
    new Section(new LMyHandler()) // place it before LExtensibilityGlobals
);

But even in older versions this was a regular list like:

List<ISection> map =
[
    new Section(new LProject()),
    new Section(new LSolutionConfigurationPlatforms()),
    new Section(new LProjectConfigurationPlatforms()),
    ...
];

Default skeleton and merging

2.7+ SlnWriter got a default skeleton. You no longer need to create a new map just to apply your handlers if you simply have nothing to reuse, e.g. sln.Result.Map above.

Default skeleton defines a empty map that contains the described handlers, with their order. Everything you need to create from scratch.

Moreover, SlnWriter will also merge the map and skeleton when saving the result:

await w.WriteAsync(); // write using the default skeleton
await w.WriteAsync(map); // write using map after merging with the default skeleton

Note default skeleton can be changed to any other if needed.