Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactor(compiler): move matchSource into base metadata
Moves the `matchSource` into the base metadata so the binder can use it.
  • Loading branch information
crisbeto committed Apr 2, 2026
commit 63838857e78ffdf1ef16d4d2746432a2c385af74
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import {
ViewEncapsulation,
DirectiveMatcher,
SelectorlessMatcher,
MatchSource,
} from '@angular/compiler';
import ts from 'typescript';

Expand Down Expand Up @@ -73,7 +74,6 @@ import {
DirectiveMeta,
extractDirectiveTypeCheckMeta,
HostDirectivesResolver,
MatchSource,
MetadataReader,
MetadataRegistry,
MetaKind,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
ConstantPool,
FactoryTarget,
makeBindingParser,
MatchSource,
R3ClassMetadata,
R3DirectiveMetadata,
R3TargetBinder,
Expand All @@ -33,7 +34,6 @@ import {
extractDirectiveTypeCheckMeta,
HostDirectiveMeta,
InputMapping,
MatchSource,
MetadataReader,
MetadataRegistry,
MetaKind,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
R3TargetBinder,
SelectorMatcher,
TmplAstElement,
MatchSource,
} from '@angular/compiler';
import ts from 'typescript';

Expand Down Expand Up @@ -137,6 +138,7 @@ runInEachFileSystem(() => {
animationTriggerNames: null,
ngContentSelectors: null,
preserveWhitespaces: false,
matchSource: MatchSource.Selector,
};
matcher.addSelectables(CssSelector.parse('[dir]'), [dirMeta]);

Expand Down
2 changes: 2 additions & 0 deletions packages/compiler-cli/src/ngtsc/indexer/test/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
BoundTarget,
CssSelector,
DirectiveMatcher,
MatchSource,
parseTemplate,
ParseTemplateOptions,
R3TargetBinder,
Expand Down Expand Up @@ -69,6 +70,7 @@ export function getBoundTemplate(
animationTriggerNames: null,
ngContentSelectors: null,
preserveWhitespaces: false,
matchSource: MatchSource.Selector,
}));

let matcher: DirectiveMatcher<ComponentMeta>;
Expand Down
12 changes: 1 addition & 11 deletions packages/compiler-cli/src/ngtsc/metadata/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
Expression,
SchemaMetadata,
ExternalReference,
MatchSource,
} from '@angular/compiler';
import ts from 'typescript';

Expand Down Expand Up @@ -134,17 +135,6 @@ export enum MetaKind {
NgModule,
}

/**
* Possible ways that a directive can be matched.
*/
export enum MatchSource {
/** The directive was matched by its selector. */
Selector,

/** The directive was applied as a host directive. */
HostDirective,
}

/** Metadata for a single input mapping. */
export type InputMapping = InputOrOutput & {
required: boolean;
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler-cli/src/ngtsc/metadata/src/dts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* found in the LICENSE file at https://angular.dev/license
*/

import {MatchSource} from '@angular/compiler';
import ts from 'typescript';

import {OwningModule, Reference} from '../../imports';
Expand All @@ -21,7 +22,6 @@ import {
DirectiveMeta,
HostDirectiveMeta,
InputMapping,
MatchSource,
MetadataReader,
MetaKind,
NgModuleMeta,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
* found in the LICENSE file at https://angular.dev/license
*/

import {DirectiveMeta, InputMapping, MatchSource, MetadataReader} from '../../metadata/src/api';
import {MatchSource} from '@angular/compiler';
import {DirectiveMeta, InputMapping, MetadataReader} from '../../metadata/src/api';
import {ClassDeclaration} from '../../reflection';
import {ClassPropertyMapping, InputOrOutput} from '../src/property_mapping';

Expand Down
2 changes: 2 additions & 0 deletions packages/compiler-cli/src/ngtsc/typecheck/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
BoundTarget,
DirectiveMeta,
LegacyAnimationTriggerNames,
MatchSource,
ParseSourceSpan,
SchemaMetadata,
} from '@angular/compiler';
Expand Down Expand Up @@ -88,6 +89,7 @@ export interface TcbDirectiveMetadata {
isExplicitlyDeferred: boolean;
preserveWhitespaces: boolean;
exportAs: string[] | null;
matchSource: MatchSource;

/** Type parameters of the directive, if available. */
typeParameters: TcbTypeParameter[] | null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export function adaptTypeCheckBlockMetadata(
stringLiteralInputFields: dir.stringLiteralInputFields,
undeclaredInputFields: dir.undeclaredInputFields,
publicMethods: dir.publicMethods,
matchSource: dir.matchSource,

ref: extractRef(dir.ref as Reference<ClassDeclaration>),
isGeneric: dir.isGeneric,
Expand Down
3 changes: 2 additions & 1 deletion packages/compiler-cli/src/ngtsc/typecheck/testing/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
AST,
BindingPipe,
CssSelector,
MatchSource,
ParseSourceFile,
parseTemplate,
ParseTemplateOptions,
Expand Down Expand Up @@ -60,7 +61,6 @@ import {
DirectiveMeta,
HostDirectivesResolver,
InputMapping,
MatchSource,
MetadataReaderWithIndex,
MetaKind,
NgModuleIndex,
Expand Down Expand Up @@ -913,6 +913,7 @@ function getDirectiveMetaFromDeclaration(
isExplicitlyDeferred: false,
imports: decl.imports,
rawImports: null,
matchSource: MatchSource.Selector,
hostDirectives:
decl.hostDirectives === undefined
? null
Expand Down
14 changes: 14 additions & 0 deletions packages/compiler/src/render3/view/t2_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,20 @@ export interface DirectiveMeta {
* Only includes the legacy animation names.
*/
animationTriggerNames: LegacyAnimationTriggerNames | null;

/** Tracks how the directive was matched. */
matchSource: MatchSource;
}

/**
* Possible ways that a directive can be matched.
*/
export enum MatchSource {
/** The directive was matched by its selector. */
Selector,

/** The directive was applied as a host directive. */
HostDirective,
}

/**
Expand Down
11 changes: 10 additions & 1 deletion packages/compiler/test/render3/view/binding_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import * as e from '../../../src/expression_parser/ast';
import * as a from '../../../src/render3/r3_ast';
import {DirectiveMeta, InputOutputPropertySet} from '../../../src/render3/view/t2_api';
import {DirectiveMeta, InputOutputPropertySet, MatchSource} from '../../../src/render3/view/t2_api';
import {findMatchingDirectivesAndPipes, R3TargetBinder} from '../../../src/render3/view/t2_binder';
import {parseTemplate, ParseTemplateOptions} from '../../../src/render3/view/template';
import {CssSelector, SelectorlessMatcher, SelectorMatcher} from '../../../src/directive_matching';
Expand Down Expand Up @@ -44,6 +44,7 @@ function makeSelectorMatcher(): SelectorMatcher<DirectiveMeta[]> {
animationTriggerNames: null,
ngContentSelectors: null,
preserveWhitespaces: false,
matchSource: MatchSource.Selector,
},
]);
matcher.addSelectables(CssSelector.parse('[dir]'), [
Expand All @@ -58,6 +59,7 @@ function makeSelectorMatcher(): SelectorMatcher<DirectiveMeta[]> {
animationTriggerNames: null,
ngContentSelectors: null,
preserveWhitespaces: false,
matchSource: MatchSource.Selector,
},
]);
matcher.addSelectables(CssSelector.parse('[hasOutput]'), [
Expand All @@ -72,6 +74,7 @@ function makeSelectorMatcher(): SelectorMatcher<DirectiveMeta[]> {
animationTriggerNames: null,
ngContentSelectors: null,
preserveWhitespaces: false,
matchSource: MatchSource.Selector,
},
]);
matcher.addSelectables(CssSelector.parse('[hasInput]'), [
Expand All @@ -86,6 +89,7 @@ function makeSelectorMatcher(): SelectorMatcher<DirectiveMeta[]> {
animationTriggerNames: null,
ngContentSelectors: null,
preserveWhitespaces: false,
matchSource: MatchSource.Selector,
},
]);
matcher.addSelectables(CssSelector.parse('[sameSelectorAsInput]'), [
Expand All @@ -100,6 +104,7 @@ function makeSelectorMatcher(): SelectorMatcher<DirectiveMeta[]> {
animationTriggerNames: null,
ngContentSelectors: null,
preserveWhitespaces: false,
matchSource: MatchSource.Selector,
},
]);
matcher.addSelectables(CssSelector.parse('comp'), [
Expand All @@ -114,6 +119,7 @@ function makeSelectorMatcher(): SelectorMatcher<DirectiveMeta[]> {
animationTriggerNames: null,
ngContentSelectors: null,
preserveWhitespaces: false,
matchSource: MatchSource.Selector,
},
]);

Expand All @@ -133,6 +139,7 @@ function makeSelectorMatcher(): SelectorMatcher<DirectiveMeta[]> {
animationTriggerNames: null,
ngContentSelectors: null,
preserveWhitespaces: false,
matchSource: MatchSource.Selector,
},
]);
}
Expand Down Expand Up @@ -282,6 +289,7 @@ describe('t2 binding', () => {
animationTriggerNames: null,
ngContentSelectors: null,
preserveWhitespaces: false,
matchSource: MatchSource.Selector,
},
]);
const binder = new R3TargetBinder(matcher);
Expand Down Expand Up @@ -1039,6 +1047,7 @@ describe('t2 binding', () => {
preserveWhitespaces: false,
animationTriggerNames: null,
isComponent: false,
matchSource: MatchSource.Selector,
};

function makeSelectorlessMatcher(
Expand Down