Skip to content
Marc Laval edited this page Jan 22, 2015 · 4 revisions

Compiler

Process

The compilation process takes a component and a DOM element as input. It returns a ProtoView object as the result.
To build it, the process defines a set of steps which are recursively executed on all element nodes of the DOM tree, from the root to the leafs. This is orchestrated by the CompilePipeline and the CompileControl classes.
During the process, a temporary tree of CompileElement is built, matching the DOM tree. It is used to persist data from one step to the next ones.
When processing a node, some steps can create additional CompileElement objects. They are processed once all children have been processed (see ViewSplitter).
All the code is available in core/src/compiler/pipeline folder.

Pipeline

Each step writes and reads in the CompileElement object.

  1. ViewSplitter
    See inline documentation.
    Writes: isViewRoot, variableBindings, propertyBindings

  2. PropertyBindingParser
    Parses the attributes of the element: bind-foo, let-foo, on-foo, [foo], (foo) and interpolation (foo="{{bar}}").
    Writes: propertyBindings, eventBindings, variableBindings.

  3. DirectiveParser
    Parses directives using the SelectorMatcher and the CssSelector classes. It matches the directives' selectors with the element: class names, attributes, already found property and variable bindings.
    Writes: decoratorDirectives, templateDirective, componentDirective
    Reads: propertyBindings, variableBindings

  4. TextInterpolationParser
    Parses text nodes to find interpolated expressions.
    Writes: textNodeBindings

  5. ElementBindingMarker
    Flags the CompileElement if at least one binding exist, and adds a class to the DOM element: ng-binding
    Writes: hasBindings
    Reads: textNodeBindings, propertyBindings, variableBindings, eventBindings, decoratorDirectives, componentDirective, templateDirective

  6. ProtoViewBuilder
    Creates a new ProtoView if the element is a root view (with the current element and a new ProtoChangeDetector), it references the parent's PV. If created, it also adds a reference in the parent as a nested PV, and binds variableBindings of parent to the new PV.
    Otherwise, only a reference to the parent's one is added.
    Writes: inheritedProtoView, inheritedElementBinder.nestedProtoView (parent)
    Reads: isViewRoot, inheritedProtoView (parent), variableBindings (parent)

  7. ProtoElementInjectorBuilder
    Creates a new ProtoElementInjector if there are directives on the element (step 3), it references the parent's PEI. A DirectiveBinding object is created for each directive, starting with the component directive.
    Otherwise, only a reference to the parent's one is added.
    Writes: inheritedProtoElementInjector, distanceToParentInjector
    Reads: isViewRoot, inheritedProtoView, decoratorDirectives, componentDirective, templateDirective, inheritedProtoElementInjector (parent)

  8. ElementBinderBuilder
    If the element has any binding (step 5), it creates a new ElementBinder and adds it to the ProtoView.
    Then it binds text nodes, element properties, events and directives. These bindings are done by the ProtoView, it adds references in the ElementBinder just created, and also adds Memento objects in the PV's ProtoChangeDetector (in fact by adding the ProtoRecords generated by a ProtoChangeDetector).
    Otherwise, only a reference to the parent's one is added.
    Writes: inheritedElementBinder
    Reads: hasBindings, inheritedProtoView, inheritedProtoElementInjector, textNodeBindings, propertyBindings, eventBindings, decoratorDirectives, componentDirective, templateDirective, inheritedElementBinder (parent)

Clone this wiki locally