|
Packit Service |
7770af |
This document is mainly intended for developers!
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
# Documenting some of the source map internals
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Since source maps are somewhat a black box to all LibSass maintainers, [I](@mgreter) will try to document my findings with source maps in LibSass, as I come across them. This document will also brievely explain how LibSass parses the source and how it outputs the result.
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
The main storage for SourceMap mappings is the `mappings` vector:
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
```
|
|
Packit Service |
7770af |
# in source_map.hpp
|
|
Packit Service |
7770af |
vector<Mapping> mappings
|
|
Packit Service |
7770af |
# in mappings.hpp
|
|
Packit Service |
7770af |
struct Mapping ...
|
|
Packit Service |
7770af |
Position original_position;
|
|
Packit Service |
7770af |
Position generated_position;
|
|
Packit Service |
7770af |
```
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
## Every parsed token has its source associated
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
LibSass uses a lexical parser. Whenever LibSass finds a token of interest, it creates a specific `AST_Node`, which will hold a reference to the input source with line/column information. `AST_Node` is the base class for all parsed items. They are declared in `ast.hpp` and are used in `parser.hpp`. Here a simple example:
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
```
|
|
Packit Service |
7770af |
if (lex< custom_property_name >()) {
|
|
Packit Service |
7770af |
Sass::String* prop = new (ctx.mem) String_Constant(path, source_position, lexed);
|
|
Packit Service |
7770af |
return new (ctx.mem) Declaration(path, prop->position(), prop, ...);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
```
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
## How is the `source_position` calculated
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
This is automatically done with `lex` in `parser.hpp`. Whenever something is lexed, the `source_position` is updated. But be aware that `source_position` points to the begining of the parsed text. If you need a mapping for the position where the parsing ended, you need to add another call to `lex` (to match nothing)!
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
```
|
|
Packit Service |
7770af |
lex< exactly < empty_str > >();
|
|
Packit Service |
7770af |
end = new (ctx.mem) String_Constant(path, source_position, lexed);
|
|
Packit Service |
7770af |
```
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
## How are mappings for the output created
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
So far we have collected all needed data for all tokens in the input stream. We can now use this information to create mappings when we put things into the output stream. Mappings are created via the `add_mappings` method:
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
```
|
|
Packit Service |
7770af |
# in source_map.hpp
|
|
Packit Service |
7770af |
void add_mapping(AST_Node* node);
|
|
Packit Service |
7770af |
```
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
This method is called in two places:
|
|
Packit Service |
7770af |
- `Inspect::append_to_buffer`
|
|
Packit Service |
7770af |
- `Output_[Nested|Compressed]::append_to_buffer`
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Mappings can only be created for things that have been parsed into a `AST_Node`. Otherwise we do not have the information to create the mappings, which is the reason why LibSass currently only maps the most important tokens in source maps.
|