Module: lib/compiler/atlas/source

Reading an Avenx component file without losing where things are.

Why this exists

By the time the compiler validates a template it has already rewritten it: imports are stripped, comments removed, <state>/<computed>/<action>/ <resource>/<contract> blocks deleted, style scoping applied, data-ax-bind expanded. Offsets into that string do not point at anything a developer can open in an editor.

Atlas reports file and line for every relationship it records, so it cannot use those offsets. Instead it masks the original source: declaration blocks and comments are replaced character-for-character with spaces, and newlines are kept. The result is the same length as the file, so an offset into the mask is an offset into the file, and lineOf turns it into the line the developer wrote.

Masking rather than slicing is what keeps this honest. A slice would need an offset table that has to be maintained in step with every future template transformation; a mask cannot drift, because it never moves anything.

Source:

Members

(inner, constant) DECLARATION_PATTERNS :Array:.<RegExp:>

Regions of a component file that are declarations rather than template.

The patterns mirror the ones extractTemplate uses to strip the same regions, so the mask and the compiled template agree on what the template is. Order matters only in that block forms must precede self-closing forms.

Type:
  • Array:.<RegExp:>
Source:

Methods

(static) declarationLines(content) → {Object}

Finds the line of every named declaration in one pass.

The obvious implementation asks lineOf for each name in turn, which rescans the whole file per declaration and counts newlines from the start each time — quadratic in a component with many declarations, for a fact that one pass can produce.

Parameters:
Name Type Description
content string

The component source.

Source:
Returns:

Declaration lines, keyed by name.

Type
Object

(static) escapeName(name) → {string}

Escapes a declared name for use inside a regular expression.

Parameters:
Name Type Description
name string

The name.

Source:
Returns:

The escaped name.

Type
string

(static) lineIndex(content) → {Array:.<number:>}

Builds an index of line start offsets for fast offset-to-line lookup.

Component files are small, but every binding, handler and directive asks for a line, so scanning the string per lookup would be quadratic in the number of bindings.

Parameters:
Name Type Description
content string

The source.

Source:
Returns:

Offsets at which each line begins.

Type
Array:.<number:>

(static) lineOf(content, pattern) → {number|null}

Finds the 1-based line a declaration sits on.

Used for the declarations Atlas records by name rather than by offset — a <state> key, a <computed>, an <action> — where the name is what the developer would search for.

Parameters:
Name Type Description
content string

The file contents.

pattern RegExp

What to look for.

Source:
Returns:

The line, or null when the pattern does not match.

Type
number | null

(static) maskDeclarations(content) → {string}

Blanks out everything in a component file that is not template markup.

The returned string has the same length as the input, so any offset into it is an offset into the original file.

Parameters:
Name Type Description
content string

The component source.

Source:
Returns:

The masked source.

Type
string

(static) positionAt(starts, offset) → {Object}

Converts an offset into a 1-based line and column.

Parameters:
Name Type Description
starts Array:.<number:>

The index from lineIndex.

offset number

An offset into the same source.

Source:
Returns:

The position.

Type
Object

(static) stateKeyLine(content, key) → {number|null}

Locates the line of a <state> key.

State keys share one tag, so the attribute is what is searched for rather than the tag. When the key cannot be found — an unusual formatting — the <state> tag's own line is a truthful fallback.

Parameters:
Name Type Description
content string

The component source.

key string

The state key.

Source:
Returns:

The line, or null.

Type
number | null

(inner) blank(text) → {string}

Replaces a region with spaces, keeping newlines so line numbers survive.

Parameters:
Name Type Description
text string

The region's text.

Source:
Returns:

A same-length blank of it.

Type
string