| 172 | * target. |
| 173 | */ |
| 174 | export class R3TargetBinder<DirectiveT extends DirectiveMeta> implements TargetBinder<DirectiveT> { |
| 175 | constructor( |
| 176 | private directiveMatcher: DirectiveMatcher<DirectiveT> | null, |
| 177 | private foreignComponentMatcher: SelectorlessMatcher<ForeignComponentMeta> | null = null, |
| 178 | ) {} |
| 179 | |
| 180 | /** |
| 181 | * Perform a binding operation on the given `Target` and return a `BoundTarget` which contains |
| 182 | * metadata about the types referenced in the template. |
| 183 | */ |
| 184 | bind(target: Target<DirectiveT>): BoundTarget<DirectiveT> { |
| 185 | if (!target.template && !target.host) { |
| 186 | throw new Error('Empty bound targets are not supported'); |
| 187 | } |
| 188 | |
| 189 | const directives: MatchedDirectives<DirectiveT> = new Map(); |
| 190 | const foreignComponents = new Map<Element, ForeignComponentMeta>(); |
| 191 | const eagerDirectives: DirectiveT[] = []; |
| 192 | const missingDirectives = new Set<string>(); |
| 193 | const bindings: BindingsMap<DirectiveT> = new Map(); |
| 194 | const references: ReferenceMap<DirectiveT> = new Map(); |
| 195 | const scopedNodeEntities: ScopedNodeEntities = new Map(); |
| 196 | const expressions = new Map<AST, TemplateEntity>(); |
| 197 | const symbols = new Map<TemplateEntity, Template>(); |
| 198 | const nestingLevel = new Map<ScopedNode, number>(); |
| 199 | const usedPipes = new Set<string>(); |
| 200 | const eagerPipes = new Set<string>(); |
| 201 | const deferBlocks: DeferBlockScopes = []; |
| 202 | const conflictingHostDirectiveBindings = new Map< |
| 203 | DirectiveOwner, |
| 204 | ConflictingHostDirectiveBinding<DirectiveT>[] |
| 205 | >(); |
| 206 | |
| 207 | if (target.template) { |
| 208 | // First, parse the template into a `Scope` structure. This operation captures the syntactic |
| 209 | // scopes in the template and makes them available for later use. |
| 210 | const scope = Scope.apply(target.template); |
| 211 | |
| 212 | // Use the `Scope` to extract the entities present at every level of the template. |
| 213 | extractScopedNodeEntities(scope, scopedNodeEntities); |
| 214 | |
| 215 | // Next, perform directive matching on the template using the `DirectiveBinder`. This returns: |
| 216 | // - directives: Map of nodes (elements & ng-templates) to the directives on them. |
| 217 | // - bindings: Map of inputs, outputs, and attributes to the directive/element that claims |
| 218 | // them. TODO(alxhub): handle multiple directives claiming an input/output/etc. |
| 219 | // - references: Map of #references to their targets. |
| 220 | DirectiveBinder.apply( |
| 221 | target.template, |
| 222 | this.directiveMatcher, |
| 223 | this.foreignComponentMatcher, |
| 224 | directives, |
| 225 | foreignComponents, |
| 226 | eagerDirectives, |
| 227 | missingDirectives, |
| 228 | bindings, |
| 229 | references, |
| 230 | conflictingHostDirectiveBindings, |
| 231 | ); |
nothing calls this directly
no outgoing calls
no test coverage detected