Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions goldens/public-api/compiler-cli/error_code.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ export enum ErrorCode {
PIPE_MISSING_NAME = 2002,
SCHEMA_INVALID_ATTRIBUTE = 8002,
SCHEMA_INVALID_ELEMENT = 8001,
SERVICE_CONSTRUCTOR_DI = 2028,
SKIP_HYDRATION_NOT_STATIC = 8108,
SPLIT_TWO_WAY_BINDING = 8007,
SUFFIX_NOT_SUPPORTED = 8106,
Expand Down
21 changes: 21 additions & 0 deletions goldens/public-api/core/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1764,6 +1764,27 @@ export interface SelfDecorator {
new (): Self;
}

// @public
export interface Service {
autoProvided?: boolean;
factory?: () => unknown;
}

// @public
export const Service: ServiceDecorator;

// @public
export interface ServiceDecorator {
(): TypeDecorator;
(options?: {
autoProvided: false;
}): TypeDecorator;
(options?: {
autoProvided?: true;
factory?: () => unknown;
}): TypeDecorator;
}

// @public
export function setTestabilityGetter(getter: GetTestability): void;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {PartialNgModuleLinkerVersion1} from './partial_ng_module_linker_1';
import {PartialPipeLinkerVersion1} from './partial_pipe_linker_1';
import {PLACEHOLDER_VERSION} from './util';
import {AbsoluteFsPath} from '../../../../src/ngtsc/file_system/src/types';
import {PartialServiceLinkerVersion1} from './partial_service_linker_1';

export const ɵɵngDeclareDirective = 'ɵɵngDeclareDirective';
export const ɵɵngDeclareClassMetadata = 'ɵɵngDeclareClassMetadata';
Expand All @@ -33,6 +34,7 @@ export const ɵɵngDeclareInjector = 'ɵɵngDeclareInjector';
export const ɵɵngDeclareNgModule = 'ɵɵngDeclareNgModule';
export const ɵɵngDeclarePipe = 'ɵɵngDeclarePipe';
export const ɵɵngDeclareClassMetadataAsync = 'ɵɵngDeclareClassMetadataAsync';
export const ɵɵngDeclareService = 'ɵɵngDeclareService';
export const declarationFunctions = [
ɵɵngDeclareDirective,
ɵɵngDeclareClassMetadata,
Expand All @@ -43,6 +45,7 @@ export const declarationFunctions = [
ɵɵngDeclareNgModule,
ɵɵngDeclarePipe,
ɵɵngDeclareClassMetadataAsync,
ɵɵngDeclareService,
];

export interface LinkerRange<TExpression> {
Expand Down Expand Up @@ -119,6 +122,9 @@ export function createLinkerMap<TStatement, TExpression, TType>(
linkers.set(ɵɵngDeclarePipe, [
{range: LATEST_VERSION_RANGE, linker: new PartialPipeLinkerVersion1()},
]);
linkers.set(ɵɵngDeclareService, [
{range: LATEST_VERSION_RANGE, linker: new PartialServiceLinkerVersion1()},
]);

return linkers;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {
compileService,
ConstantPool,
R3DeclareServiceMetadata,
R3PartialDeclaration,
R3ServiceMetadata,
} from '@angular/compiler';

import {AstObject} from '../../ast/ast_value';
import {FatalLinkerError} from '../../fatal_linker_error';

import {LinkedDefinition, PartialLinker} from './partial_linker';
import {wrapReference} from './util';

/**
* A `PartialLinker` that is designed to process `ɵɵngDeclareService()` call expressions.
*/
export class PartialServiceLinkerVersion1<TExpression> implements PartialLinker<TExpression> {
linkPartialDeclaration(
constantPool: ConstantPool,
metaObj: AstObject<R3PartialDeclaration, TExpression>,
): LinkedDefinition {
const meta = toR3ServiceMeta(metaObj);
return compileService(meta, /* resolveForwardRefs */ false);
}
}

/**
* Derives the `R3ServiceMetadata` structure from the AST object.
*/
export function toR3ServiceMeta<TExpression>(
metaObj: AstObject<R3DeclareServiceMetadata, TExpression>,
): R3ServiceMetadata {
const typeExpr = metaObj.getValue('type');
const typeName = typeExpr.getSymbolName();
if (typeName === null) {
throw new FatalLinkerError(
typeExpr.expression,
'Unsupported type, its name could not be determined',
);
}

const meta: R3ServiceMetadata = {
name: typeName,
type: wrapReference(typeExpr.getOpaque()),
typeArgumentCount: 0,
autoProvided: metaObj.has('autoProvided') ? metaObj.getBoolean('autoProvided') : undefined,
factory: metaObj.has('factory') ? metaObj.getOpaque('factory') : undefined,
};

return meta;
}
Loading
Loading