# 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].

   [a parser]: ../../parse/README.md
   [the evaluator]: ../../visitor/async_evaluate.dart
   [Sass AST]: ../sass/README.md

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.

[`Value`]: ../../value/README.md
[the serializer]: ../../visitor/serialize.dart

## 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.

[action at a distance]: https://en.wikipedia.org/wiki/Action_at_a_distance_(computer_programming)

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.

[`modifiable`]: modifiable

(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.
