Skip to content

Latest commit

 

History

History
52 lines (38 loc) · 2.37 KB

README.md

File metadata and controls

52 lines (38 loc) · 2.37 KB

CSS Abstract Syntax Tree

This directory contains the abstract syntax tree that represents a plain CSS file generated by Sass compilation. It differs from other Sass ASTs in two major ways:

  1. Instead of being created by a parser, it's created by the evaluator as it traverses the Sass AST.

  2. Because of various Sass features like @extend and at-rule hoisting, the CSS AST is mutable even though all other ASTs are immutable.

Note: the CSS AST doesn't have its own representation of declaration values. Instead, declaration values are represented as Value objects. This does mean that a CSS AST can be in a state where some of its values aren't representable in plain CSS (such as maps)—in this case, the serializer will emit an error.

Mutable and Immutable Views

Internally, the CSS AST is mutable to allow for operations like hoisting rules to the root of the AST and updating existing selectors when @extend rules are encountered. However, because mutability poses a high risk for "spooky action at a distance", we limit access to mutating APIs exclusively to the evaluator.

We do this by having an unmodifiable interface (written in this directory) for each CSS AST node which only exposes members that don't modify the node in question. The implementations of those interfaces, which do have modifying methods, live in the modifiable directory. We then universally refer to the immutable node interfaces except specifically in the evaluator, and the type system automatically ensures we don't accidentally mutate anything we don't intend to.

(Of course, it's always possible to cast an immutable node type to a mutable one, but that's a very clear code smell that a reviewer can easily identify.)

CSS Source Files

A lesser-known fact about Sass is that it actually supports three syntaxes for its source files: SCSS, the indented syntax, and plain CSS. But even when it parses plain CSS, it uses the Sass AST rather than the CSS AST to represent it so that parsing logic can easily be shared with the other stylesheet parsers.