build: remove usages of useDefineForClassFields: false (#58297)

When setting `"useDefineForClassFields": false`, static fields are compiled within a block that relies on the `this` context. This output makes it more difficult for bundlers to treeshake and eliminate unused code.

PR Close #58297
This commit is contained in:
Alan Agius
2024-10-22 07:03:51 +00:00
committed by Alex Rickabaugh
parent 395cb34599
commit 93c3f7a931
38 changed files with 219 additions and 367 deletions
@@ -105,7 +105,7 @@ export class Ng1HeroComponentWrapper extends UpgradeComponent {
// The names of the input and output properties here must match the names of the
// `<` and `&` bindings in the AngularJS component that is being wrapped
@Input() hero!: Hero;
@Output() onRemove!: EventEmitter<void>;
@Output() onRemove: EventEmitter<void> = new EventEmitter();
constructor(elementRef: ElementRef, injector: Injector) {
// We must pass the name of the directive as used by AngularJS to the super
@@ -116,7 +116,7 @@ class Ng1HeroComponentWrapper extends UpgradeComponent {
// The names of the input and output properties here must match the names of the
// `<` and `&` bindings in the AngularJS component that is being wrapped.
@Input() hero!: Hero;
@Output() onRemove!: EventEmitter<void>;
@Output() onRemove: EventEmitter<void> = new EventEmitter();
constructor(elementRef: ElementRef, injector: Injector) {
// We must pass the name of the directive as used by AngularJS to the super.
@@ -103,10 +103,19 @@ export function highlightHydrationElement(el: Node, status: HydrationStatus) {
}
export function unHighlight(): void {
if (selectedElementOverlay) {
document.body.removeChild(selectedElementOverlay);
selectedElementOverlay = null;
if (!selectedElementOverlay) {
return;
}
for (const node of document.body.childNodes) {
if (node === selectedElementOverlay) {
document.body.removeChild(selectedElementOverlay);
break;
}
}
selectedElementOverlay = null;
}
export function removeHydrationHighlights(): void {
@@ -47,7 +47,7 @@
},
"defer": {
"uncompressed": {
"main": 11497,
"main": 12094,
"polyfills": 33807,
"defer.component": 345
}
@@ -208,10 +208,6 @@ def _ngc_tsconfig(ctx, files, srcs, **kwargs):
# https://github.com/bazelbuild/rules_nodejs/blob/901df3868e3ceda177d3ed181205e8456a5592ea/third_party/github.com/bazelbuild/rules_typescript/internal/common/tsconfig.bzl#L195
# TODO(devversion): In the future, combine prodmode and devmode so we can get rid of the
# ambiguous terminology and concept that can result in slow-down for development workflows.
# TODO(alanagius): The below causes a drastic size increase when enabled (4Kb in the //integration/forms:test). This is mainly due to Babel transforms for Safari 15.
# https://github.com/angular/angular-cli/blob/3e8bdf72d6b7e2925d2822da807b726f88a77e1a/packages/angular_devkit/build_angular/src/babel/presets/application.ts#L199-L204
# https://www.diffchecker.com/9Ge3pexk
tsconfig["compilerOptions"]["useDefineForClassFields"] = False
tsconfig["compilerOptions"]["target"] = "es2022"
tsconfig["compilerOptions"]["module"] = "esnext"
@@ -128,9 +128,9 @@ import * as i0 from '@angular/core';
import { NgModule } from '@angular/core';
class A11yModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: A11yModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "0.0.0", ngImport: i0, type: A11yModule }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: A11yModule }); }
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: A11yModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "0.0.0", ngImport: i0, type: A11yModule });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: A11yModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: A11yModule, decorators: [{
type: NgModule,
@@ -157,8 +157,8 @@ import * as i0 from '@angular/core';
import { Injectable } from '@angular/core';
class MySecondService {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: MySecondService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: MySecondService, providedIn: 'root' }); }
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: MySecondService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: MySecondService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: MySecondService, decorators: [{
type: Injectable,
@@ -166,11 +166,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0", ngImport
}] });
class MyService {
secondService;
constructor(secondService) {
this.secondService = secondService;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: MyService, deps: [{ token: MySecondService }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: MyService, providedIn: 'root' }); }
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: MyService, deps: [{ token: MySecondService }], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: MyService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: MyService, decorators: [{
type: Injectable,
@@ -197,9 +198,9 @@ import * as i0 from '@angular/core';
import { NgModule } from '@angular/core';
class SecondaryModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: SecondaryModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "0.0.0", ngImport: i0, type: SecondaryModule }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: SecondaryModule }); }
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: SecondaryModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "0.0.0", ngImport: i0, type: SecondaryModule });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: SecondaryModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: SecondaryModule, decorators: [{
type: NgModule,
@@ -227,9 +228,9 @@ import * as i0 from '@angular/core';
import { NgModule } from '@angular/core';
class MyModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: MyModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "0.0.0", ngImport: i0, type: MyModule }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: MyModule }); }
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: MyModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "0.0.0", ngImport: i0, type: MyModule });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: MyModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: MyModule, decorators: [{
type: NgModule,
@@ -76,9 +76,9 @@ import * as i0 from '@angular/core';
import { NgModule } from '@angular/core';
class PortalModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: PortalModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "0.0.0", ngImport: i0, type: PortalModule }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: PortalModule }); }
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: PortalModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "0.0.0", ngImport: i0, type: PortalModule });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: PortalModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0", ngImport: i0, type: PortalModule, decorators: [{
type: NgModule,
@@ -15,6 +15,6 @@ describe('ng_module with ivy enabled', () => {
'packages/bazel/test/ngc-wrapped/ivy_enabled/test_module_default_compilation.mjs',
);
const fileContent = readFileSync(outputFile, 'utf8');
expect(fileContent).toContain(`static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent`);
expect(fileContent).toContain(`static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent`);
});
});
@@ -15,10 +15,8 @@ import {DEFAULT_LINKER_OPTIONS, LinkerOptions} from './linker_options';
import {Translator} from './translator';
export class LinkerEnvironment<TStatement, TExpression> {
readonly translator = new Translator<TStatement, TExpression>(this.factory);
readonly sourceFileLoader = this.options.sourceMapping
? new SourceFileLoader(this.fileSystem, this.logger, {})
: null;
readonly translator: Translator<TStatement, TExpression>;
readonly sourceFileLoader: SourceFileLoader | null;
private constructor(
readonly fileSystem: ReadonlyFileSystem,
@@ -26,7 +24,12 @@ export class LinkerEnvironment<TStatement, TExpression> {
readonly host: AstHost<TExpression>,
readonly factory: AstFactory<TStatement, TExpression>,
readonly options: LinkerOptions,
) {}
) {
this.translator = new Translator<TStatement, TExpression>(this.factory);
this.sourceFileLoader = this.options.sourceMapping
? new SourceFileLoader(this.fileSystem, this.logger, {})
: null;
}
static create<TStatement, TExpression>(
fileSystem: ReadonlyFileSystem,
+4 -2
View File
@@ -48,13 +48,15 @@ export class NgtscTestEnvironment {
private multiCompileHostExt: MultiCompileHostExt | null = null;
private oldProgram: Program | null = null;
private changedResources: Set<string> | null = null;
private commandLineArgs = ['-p', this.basePath];
private commandLineArgs: string[];
private constructor(
private fs: FileSystem,
readonly outDir: AbsoluteFsPath,
readonly basePath: AbsoluteFsPath,
) {}
) {
this.commandLineArgs = ['-p', this.basePath];
}
/**
* Set up a new testing environment.
+2 -14
View File
@@ -66,14 +66,7 @@ export class QueryList<T> implements Iterable<T> {
* has occurred. Or if it should fire when query is recomputed. (recomputing could resolve in
* the same result)
*/
constructor(private _emitDistinctChangesOnly: boolean = false) {
// This function should be declared on the prototype, but doing so there will cause the class
// declaration to have side-effects and become not tree-shakable. For this reason we do it in
// the constructor.
// [Symbol.iterator](): Iterator<T> { ... }
const proto = QueryList.prototype;
if (!proto[Symbol.iterator]) proto[Symbol.iterator] = symbolIterator;
}
constructor(private _emitDistinctChangesOnly: boolean = false) {}
/**
* Returns the QueryList entry at `index`.
@@ -193,10 +186,5 @@ export class QueryList<T> implements Iterable<T> {
}
}
// The implementation of `Symbol.iterator` should be declared here, but this would cause
// tree-shaking issues with `QueryList. So instead, it's added in the constructor (see comments
// there) and this declaration is left here to ensure that TypeScript considers QueryList to
// implement the Iterable interface. This is required for template type-checking of NgFor loops
// over QueryLists to work correctly, since QueryList must be assignable to NgIterable.
[Symbol.iterator]!: () => Iterator<T>;
[Symbol.iterator]: () => Iterator<T> = /** @__PURE__*/ (() => symbolIterator)();
}
+34 -19
View File
@@ -2707,11 +2707,17 @@ describe('di', () => {
standalone: false,
})
class MyComp {
tokenViaInjector = this.injector.get(NON_EXISTING_PROVIDER, null, InjectFlags.Optional);
tokenViaInjector;
constructor(
public injector: Injector,
@Inject(NON_EXISTING_PROVIDER) @Optional() public tokenViaConstructor: string,
) {}
) {
this.tokenViaInjector = this.injector.get(
NON_EXISTING_PROVIDER,
null,
InjectFlags.Optional,
);
}
}
TestBed.configureTestingModule({declarations: [MyComp]});
const fixture = TestBed.createComponent(MyComp);
@@ -2748,11 +2754,13 @@ describe('di', () => {
standalone: false,
})
class ChildComponent {
tokenViaInjector = this.injector.get(TOKEN, null, InjectFlags.SkipSelf);
tokenViaInjector;
constructor(
public injector: Injector,
@Inject(TOKEN) @SkipSelf() public tokenViaConstructor: string,
) {}
) {
this.tokenViaInjector = this.injector.get(TOKEN, null, InjectFlags.SkipSelf);
}
}
TestBed.configureTestingModule({
@@ -2774,11 +2782,13 @@ describe('di', () => {
standalone: false,
})
class DirectiveString {
tokenViaInjector = this.injector.get(TOKEN, null, InjectFlags.Host);
tokenViaInjector;
constructor(
public injector: Injector,
@Inject(TOKEN) @Host() public tokenViaConstructor: string,
) {}
) {
this.tokenViaInjector = this.injector.get(TOKEN, null, InjectFlags.Host);
}
}
@Component({
@@ -2809,21 +2819,24 @@ describe('di', () => {
standalone: false,
})
class DirectiveB {
public tokenSelfViaInjector = this.injector.get(
DirectiveA,
null,
InjectFlags.Self | InjectFlags.Optional,
);
public tokenHostViaInjector = this.injector.get(
DirectiveA,
null,
InjectFlags.Host | InjectFlags.Optional,
);
tokenSelfViaInjector;
tokenHostViaInjector;
constructor(
public injector: Injector,
@Inject(DirectiveA) @Self() @Optional() public tokenSelfViaConstructor: DirectiveA,
@Inject(DirectiveA) @Host() @Optional() public tokenHostViaConstructor: DirectiveA,
) {}
) {
this.tokenSelfViaInjector = this.injector.get(
DirectiveA,
null,
InjectFlags.Self | InjectFlags.Optional,
);
this.tokenHostViaInjector = this.injector.get(
DirectiveA,
null,
InjectFlags.Host | InjectFlags.Optional,
);
}
}
@Component({
@@ -2888,8 +2901,10 @@ describe('di', () => {
@Injectable({providedIn: forwardRef(() => Module)})
class Provider {
constructor(private _dep: ProviderDep) {}
value = this._dep.getNumber() + 2;
constructor(private _dep: ProviderDep) {
this.value = this._dep.getNumber() + 2;
}
value;
}
@Component({
@@ -4050,8 +4050,10 @@ describe('styling', () => {
standalone: false,
})
class HostBindingTestComponent {
style: SafeStyle = this.sanitizer.bypassSecurityTrustStyle('color: white; display: block;');
constructor(private sanitizer: DomSanitizer) {}
style: SafeStyle;
constructor(private sanitizer: DomSanitizer) {
this.style = this.sanitizer.bypassSecurityTrustStyle('color: white; display: block;');
}
}
TestBed.configureTestingModule({declarations: [HostBindingTestComponent]});
const fixture = TestBed.createComponent(HostBindingTestComponent);
@@ -17,9 +17,6 @@
{
"name": "AfterRenderManager"
},
{
"name": "AfterRenderPhase"
},
{
"name": "AnimationAstBuilderContext"
},
@@ -566,18 +563,9 @@
{
"name": "ZoneStablePendingTask"
},
{
"name": "_AfterRenderImpl"
},
{
"name": "_AnimationDriver"
},
{
"name": "_CACHED_BODY"
},
{
"name": "_ComponentFactoryResolver"
},
{
"name": "_DOM"
},
@@ -591,11 +579,14 @@
"name": "_NullComponentFactoryResolver"
},
{
"name": "_SpecialCasedStyles"
"name": "__defProp"
},
{
"name": "__forward_ref__"
},
{
"name": "__publicField"
},
{
"name": "_applyRootElementTransformImpl"
},
@@ -20,9 +20,6 @@
{
"name": "AfterRenderManager"
},
{
"name": "AfterRenderPhase"
},
{
"name": "AnimationAstBuilderContext"
},
@@ -626,18 +623,9 @@
{
"name": "ZoneStablePendingTask"
},
{
"name": "_AfterRenderImpl"
},
{
"name": "_AnimationDriver"
},
{
"name": "_CACHED_BODY"
},
{
"name": "_ComponentFactoryResolver"
},
{
"name": "_DOM"
},
@@ -651,11 +639,14 @@
"name": "_NullComponentFactoryResolver"
},
{
"name": "_SpecialCasedStyles"
"name": "__defProp"
},
{
"name": "__forward_ref__"
},
{
"name": "__publicField"
},
{
"name": "_applyRootElementTransformImpl"
},
@@ -14,9 +14,6 @@
{
"name": "AfterRenderManager"
},
{
"name": "AfterRenderPhase"
},
{
"name": "AnonymousSubject"
},
@@ -473,12 +470,6 @@
{
"name": "ZoneStablePendingTask"
},
{
"name": "_AfterRenderImpl"
},
{
"name": "_ComponentFactoryResolver"
},
{
"name": "_DOM"
},
@@ -488,9 +479,15 @@
{
"name": "_NullComponentFactoryResolver"
},
{
"name": "__defProp"
},
{
"name": "__forward_ref__"
},
{
"name": "__publicField"
},
{
"name": "_applyRootElementTransformImpl"
},
@@ -8,6 +8,9 @@
{
"name": "APP_INITIALIZER"
},
{
"name": "AfterRenderImpl"
},
{
"name": "AfterRenderManager"
},
@@ -542,9 +545,6 @@
{
"name": "_AfterRenderImpl"
},
{
"name": "_ComponentFactoryResolver"
},
{
"name": "_DOM"
},
@@ -566,6 +566,9 @@
{
"name": "__getOwnPropNames"
},
{
"name": "__publicField"
},
{
"name": "_applyRootElementTransformImpl"
},
@@ -26,9 +26,6 @@
{
"name": "AfterRenderManager"
},
{
"name": "AfterRenderPhase"
},
{
"name": "AnonymousSubject"
},
@@ -437,9 +434,6 @@
{
"name": "NgModuleRef2"
},
{
"name": "NgOnChangesFeatureImpl"
},
{
"name": "NgZone"
},
@@ -662,12 +656,6 @@
{
"name": "ZoneStablePendingTask"
},
{
"name": "_AfterRenderImpl"
},
{
"name": "_ComponentFactoryResolver"
},
{
"name": "_DOM"
},
@@ -689,9 +677,15 @@
{
"name": "__await"
},
{
"name": "__defProp"
},
{
"name": "__forward_ref__"
},
{
"name": "__publicField"
},
{
"name": "_applyRootElementTransformImpl"
},
@@ -29,9 +29,6 @@
{
"name": "AfterRenderManager"
},
{
"name": "AfterRenderPhase"
},
{
"name": "AnonymousSubject"
},
@@ -422,9 +419,6 @@
{
"name": "NgModuleRef2"
},
{
"name": "NgOnChangesFeatureImpl"
},
{
"name": "NgZone"
},
@@ -647,12 +641,6 @@
{
"name": "ZoneStablePendingTask"
},
{
"name": "_AfterRenderImpl"
},
{
"name": "_ComponentFactoryResolver"
},
{
"name": "_DOM"
},
@@ -674,9 +662,15 @@
{
"name": "__await"
},
{
"name": "__defProp"
},
{
"name": "__forward_ref__"
},
{
"name": "__publicField"
},
{
"name": "_applyRootElementTransformImpl"
},
@@ -11,9 +11,6 @@
{
"name": "AfterRenderManager"
},
{
"name": "AfterRenderPhase"
},
{
"name": "AnonymousSubject"
},
@@ -359,12 +356,6 @@
{
"name": "ZoneStablePendingTask"
},
{
"name": "_AfterRenderImpl"
},
{
"name": "_ComponentFactoryResolver"
},
{
"name": "_DOM"
},
@@ -374,9 +365,15 @@
{
"name": "_NullComponentFactoryResolver"
},
{
"name": "__defProp"
},
{
"name": "__forward_ref__"
},
{
"name": "__publicField"
},
{
"name": "_applyRootElementTransformImpl"
},
@@ -14,9 +14,6 @@
{
"name": "AfterRenderManager"
},
{
"name": "AfterRenderPhase"
},
{
"name": "AnonymousSubject"
},
@@ -524,12 +521,6 @@
{
"name": "ZoneStablePendingTask"
},
{
"name": "_AfterRenderImpl"
},
{
"name": "_ComponentFactoryResolver"
},
{
"name": "_DOM"
},
@@ -545,9 +536,15 @@
{
"name": "__await"
},
{
"name": "__defProp"
},
{
"name": "__forward_ref__"
},
{
"name": "__publicField"
},
{
"name": "_applyRootElementTransformImpl"
},
@@ -1,52 +1,16 @@
[
{
"name": "AfterRenderPhase"
},
{
"name": "AnonymousSubject"
},
{
"name": "BehaviorSubject"
},
{
"name": "CIRCULAR"
},
{
"name": "COMPLETE_NOTIFICATION"
},
{
"name": "ChangeDetectionScheduler"
},
{
"name": "ConsumerObserver"
},
{
"name": "DestroyRef"
},
{
"name": "EMPTY_ARRAY"
},
{
"name": "EMPTY_OBSERVER"
},
{
"name": "EMPTY_PAYLOAD"
},
{
"name": "EMPTY_SUBSCRIPTION"
},
{
"name": "ENVIRONMENT_INITIALIZER"
},
{
"name": "EnvironmentInjector"
},
{
"name": "ErrorHandler"
},
{
"name": "EventEmitter"
},
{
"name": "INJECTOR"
},
@@ -92,42 +56,18 @@
{
"name": "NULL_INJECTOR"
},
{
"name": "NgZone"
},
{
"name": "NodeInjectorDestroyRef"
},
{
"name": "NullInjector"
},
{
"name": "ObjectUnsubscribedError"
},
{
"name": "Observable"
},
{
"name": "PendingTasksInternal"
},
{
"name": "R3Injector"
},
{
"name": "RuntimeError"
},
{
"name": "SafeSubscriber"
},
{
"name": "ScopedService"
},
{
"name": "Subject"
},
{
"name": "Subscriber"
},
{
"name": "Subscription"
},
@@ -141,16 +81,13 @@
"name": "UnsubscriptionError"
},
{
"name": "_AfterRenderImpl"
},
{
"name": "_Injector"
"name": "__defProp"
},
{
"name": "__forward_ref__"
},
{
"name": "_bind"
"name": "__publicField"
},
{
"name": "_currentInjector"
@@ -161,30 +98,12 @@
{
"name": "activeConsumer"
},
{
"name": "angularZoneInstanceIdProperty"
},
{
"name": "arrRemove"
},
{
"name": "assertNotDestroyed"
},
{
"name": "bind"
},
{
"name": "checkStable"
},
{
"name": "config"
},
{
"name": "context"
},
{
"name": "convertToBitFlags"
},
{
"name": "createErrorClass"
},
@@ -194,18 +113,12 @@
{
"name": "createLFrame"
},
{
"name": "createNotification"
},
{
"name": "deepForEach"
},
{
"name": "deepForEachProvider"
},
{
"name": "errorContext"
},
{
"name": "execFinalizer"
},
@@ -221,9 +134,6 @@
{
"name": "getFactoryDef"
},
{
"name": "getInjectImplementation"
},
{
"name": "getInjectableDef"
},
@@ -236,33 +146,12 @@
{
"name": "getOwnDefinition"
},
{
"name": "getPromiseCtor"
},
{
"name": "handleStoppedNotification"
},
{
"name": "handleUnhandledError"
},
{
"name": "hasApplyArgsData"
},
{
"name": "identity"
},
{
"name": "importProvidersFrom"
},
{
"name": "inject"
},
{
"name": "injectArgs"
},
{
"name": "injectDestroyRef"
},
{
"name": "injectInjectorOnly"
},
@@ -275,18 +164,12 @@
{
"name": "internalImportProvidersFrom"
},
{
"name": "isAngularZoneProperty"
},
{
"name": "isEnvironmentProviders"
},
{
"name": "isFunction"
},
{
"name": "isSubscription"
},
{
"name": "isTypeProvider"
},
@@ -296,24 +179,6 @@
{
"name": "makeRecord"
},
{
"name": "ngZoneInstanceId"
},
{
"name": "noop"
},
{
"name": "noop2"
},
{
"name": "observable"
},
{
"name": "onEnter"
},
{
"name": "onLeave"
},
{
"name": "processInjectorTypesWithProviders"
},
@@ -332,12 +197,6 @@
{
"name": "stringify"
},
{
"name": "timeoutProvider"
},
{
"name": "updateMicroTaskStatus"
},
{
"name": "walkProviderTree"
},
@@ -32,9 +32,6 @@
{
"name": "AfterRenderManager"
},
{
"name": "AfterRenderPhase"
},
{
"name": "AnonymousSubject"
},
@@ -458,9 +455,6 @@
{
"name": "NgModuleRef2"
},
{
"name": "NgOnChangesFeatureImpl"
},
{
"name": "NgZone"
},
@@ -794,12 +788,6 @@
{
"name": "ZoneStablePendingTask"
},
{
"name": "_AfterRenderImpl"
},
{
"name": "_ComponentFactoryResolver"
},
{
"name": "_DOM"
},
@@ -815,9 +803,18 @@
{
"name": "__await"
},
{
"name": "__defProp"
},
{
"name": "__forward_ref__"
},
{
"name": "__publicField"
},
{
"name": "_a"
},
{
"name": "_applyRootElementTransformImpl"
},
@@ -11,9 +11,6 @@
{
"name": "AfterRenderManager"
},
{
"name": "AfterRenderPhase"
},
{
"name": "AnonymousSubject"
},
@@ -419,12 +416,6 @@
{
"name": "ZoneStablePendingTask"
},
{
"name": "_AfterRenderImpl"
},
{
"name": "_ComponentFactoryResolver"
},
{
"name": "_DOM"
},
@@ -434,9 +425,15 @@
{
"name": "_NullComponentFactoryResolver"
},
{
"name": "__defProp"
},
{
"name": "__forward_ref__"
},
{
"name": "__publicField"
},
{
"name": "_applyRootElementTransformImpl"
},
@@ -14,9 +14,6 @@
{
"name": "AfterRenderManager"
},
{
"name": "AfterRenderPhase"
},
{
"name": "AnonymousSubject"
},
@@ -545,12 +542,6 @@
{
"name": "ZoneStablePendingTask"
},
{
"name": "_AfterRenderImpl"
},
{
"name": "_ComponentFactoryResolver"
},
{
"name": "_DOM"
},
@@ -566,9 +557,15 @@
{
"name": "_NullComponentFactoryResolver"
},
{
"name": "__defProp"
},
{
"name": "__forward_ref__"
},
{
"name": "__publicField"
},
{
"name": "_applyRootElementTransformImpl"
},
@@ -103,7 +103,7 @@ export class Ng1HeroComponentWrapper extends UpgradeComponent {
// The names of the input and output properties here must match the names of the
// `<` and `&` bindings in the AngularJS component that is being wrapped
@Input() hero!: Hero;
@Output() onRemove!: EventEmitter<void>;
@Output() onRemove: EventEmitter<void> = new EventEmitter();
constructor(elementRef: ElementRef, injector: Injector) {
// We must pass the name of the directive as used by AngularJS to the super
@@ -113,8 +113,10 @@ const appModule = angular
controller: [
'ng2AService',
class Ng1AController {
value = this.ng2AService.getValue();
constructor(private ng2AService: Ng2AService) {}
value: string;
constructor(private ng2AService: Ng2AService) {
this.value = this.ng2AService.getValue();
}
},
],
})
@@ -116,7 +116,7 @@ class Ng1HeroComponentWrapper extends UpgradeComponent {
// The names of the input and output properties here must match the names of the
// `<` and `&` bindings in the AngularJS component that is being wrapped.
@Input() hero!: Hero;
@Output() onRemove!: EventEmitter<void>;
@Output() onRemove: EventEmitter<void> = new EventEmitter();
constructor(elementRef: ElementRef, injector: Injector) {
// We must pass the name of the directive as used by AngularJS to the super.
+3 -3
View File
@@ -1538,7 +1538,7 @@ import {asyncValidator} from './util';
describe('can be extended', () => {
it('by a simple strongly-typed array', () => {
abstract class StringFormArray extends FormArray {
override value!: string[];
override value: string[] = [];
}
});
@@ -1546,8 +1546,8 @@ import {asyncValidator} from './util';
abstract class OtherTypedFormArray<
TControls extends Array<AbstractControl<unknown>>,
> extends FormArray {
override controls!: TControls;
override value!: never[];
override controls: TControls = {} as TControls;
override value: string[] = [];
}
});
});
+15 -8
View File
@@ -11,7 +11,6 @@ import {
ASTWithSource,
BindingPipe,
BindingType,
Call,
EmptyExpr,
ImplicitReceiver,
LiteralPrimitive,
@@ -41,6 +40,7 @@ import {
PotentialDirective,
SymbolKind,
TemplateDeclarationSymbol,
TemplateTypeChecker,
} from '@angular/compiler-cli/src/ngtsc/typecheck/api';
import ts from 'typescript';
@@ -123,12 +123,12 @@ function buildBlockSnippet(insertSnippet: boolean, blockName: string, withParens
* @param N type of the template node in question, narrowed accordingly.
*/
export class CompletionBuilder<N extends TmplAstNode | AST> {
private readonly typeChecker = this.compiler.getCurrentProgram().getTypeChecker();
private readonly templateTypeChecker = this.compiler.getTemplateTypeChecker();
private readonly nodeParent = this.targetDetails.parent;
private readonly nodeContext = nodeContextFromTarget(this.targetDetails.context);
private readonly template = this.targetDetails.template;
private readonly position = this.targetDetails.position;
private readonly typeChecker: ts.TypeChecker;
private readonly templateTypeChecker: TemplateTypeChecker;
private readonly nodeParent: TmplAstNode | AST | null;
private readonly nodeContext: CompletionNodeContext;
private readonly template: TmplAstTemplate | null;
private readonly position: number;
constructor(
private readonly tsLS: ts.LanguageService,
@@ -136,7 +136,14 @@ export class CompletionBuilder<N extends TmplAstNode | AST> {
private readonly component: ts.ClassDeclaration,
private readonly node: N,
private readonly targetDetails: TemplateTarget,
) {}
) {
this.typeChecker = this.compiler.getCurrentProgram().getTypeChecker();
this.templateTypeChecker = this.compiler.getTemplateTypeChecker();
this.nodeParent = this.targetDetails.parent;
this.nodeContext = nodeContextFromTarget(this.targetDetails.context);
this.template = this.targetDetails.template;
this.position = this.targetDetails.position;
}
/**
* Analogue for `ts.LanguageService.getCompletionsAtPosition`.
+5 -2
View File
@@ -26,6 +26,7 @@ import {
SymbolKind,
TcbLocation,
TemplateSymbol,
TemplateTypeChecker,
} from '@angular/compiler-cli/src/ngtsc/typecheck/api';
import ts from 'typescript';
@@ -55,12 +56,14 @@ interface HasTcbLocation {
}
export class DefinitionBuilder {
private readonly ttc = this.compiler.getTemplateTypeChecker();
private readonly ttc: TemplateTypeChecker;
constructor(
private readonly tsLS: ts.LanguageService,
private readonly compiler: NgCompiler,
) {}
) {
this.ttc = this.compiler.getTemplateTypeChecker();
}
getDefinitionAndBoundSpan(
fileName: string,
+6 -3
View File
@@ -47,8 +47,8 @@ import {
} from './utils';
export class QuickInfoBuilder {
private readonly typeChecker = this.compiler.getCurrentProgram().getTypeChecker();
private readonly parent = this.positionDetails.parent;
private readonly typeChecker: ts.TypeChecker;
private readonly parent: TmplAstNode | AST | null;
constructor(
private readonly tsLS: ts.LanguageService,
@@ -56,7 +56,10 @@ export class QuickInfoBuilder {
private readonly component: ts.ClassDeclaration,
private node: TmplAstNode | AST,
private readonly positionDetails: TemplateTarget,
) {}
) {
this.typeChecker = this.compiler.getCurrentProgram().getTypeChecker();
this.parent = this.positionDetails.parent;
}
get(): ts.QuickInfo | undefined {
if (this.node instanceof TmplAstDeferredTrigger || this.node instanceof TmplAstBlockNode) {
@@ -10,12 +10,11 @@ import {NgCompiler} from '@angular/compiler-cli/src/ngtsc/core';
import {absoluteFrom} from '@angular/compiler-cli/src/ngtsc/file_system';
import {MetaKind, PipeMeta} from '@angular/compiler-cli/src/ngtsc/metadata';
import {PerfPhase} from '@angular/compiler-cli/src/ngtsc/perf';
import {SymbolKind} from '@angular/compiler-cli/src/ngtsc/typecheck/api';
import {SymbolKind, TemplateTypeChecker} from '@angular/compiler-cli/src/ngtsc/typecheck/api';
import ts from 'typescript';
import {
convertToTemplateDocumentSpan,
createLocationKey,
FilePosition,
getParentClassMeta,
getRenameTextAndSpanAtPosition,
@@ -26,12 +25,14 @@ import {collectMemberMethods, findTightestNode} from './utils/ts_utils';
import {getTemplateInfoAtPosition, TemplateInfo} from './utils';
export class ReferencesBuilder {
private readonly ttc = this.compiler.getTemplateTypeChecker();
private readonly ttc: TemplateTypeChecker;
constructor(
private readonly tsLS: ts.LanguageService,
private readonly compiler: NgCompiler,
) {}
) {
this.ttc = this.compiler.getTemplateTypeChecker();
}
getReferencesAtPosition(filePath: string, position: number): ts.ReferenceEntry[] | undefined {
this.ttc.generateAllTypeCheckBlocks();
@@ -162,12 +163,14 @@ function isDirectRenameContext(
}
export class RenameBuilder {
private readonly ttc = this.compiler.getTemplateTypeChecker();
private readonly ttc: TemplateTypeChecker;
constructor(
private readonly tsLS: ts.LanguageService,
private readonly compiler: NgCompiler,
) {}
) {
this.ttc = this.compiler.getTemplateTypeChecker();
}
getRenameInfo(
filePath: string,
@@ -27,14 +27,17 @@ import {makeLocalePlugin} from './locale_plugin';
* message.
*/
export class SourceFileTranslationHandler implements TranslationHandler {
private sourceLocaleOptions: TranslatePluginOptions = {
...this.translationOptions,
missingTranslation: 'ignore',
};
private sourceLocaleOptions: TranslatePluginOptions;
constructor(
private fs: FileSystem,
private translationOptions: TranslatePluginOptions = {},
) {}
) {
this.sourceLocaleOptions = {
...this.translationOptions,
missingTranslation: 'ignore',
};
}
canTranslate(relativeFilePath: PathSegment | AbsoluteFsPath, _contents: Uint8Array): boolean {
return this.fs.extname(relativeFilePath) === '.js';
@@ -111,16 +111,17 @@ export class MockExtendableMessageEvent
}
export class MockNotificationEvent extends MockExtendableEvent implements NotificationEvent {
readonly notification = {
...this._notification,
close: () => undefined,
} as Notification;
readonly notification: Notification;
constructor(
private _notification: Partial<Notification>,
readonly action = '',
) {
super('notification');
this.notification = {
...this._notification,
close: () => undefined,
} as Notification;
}
}
@@ -27,11 +27,14 @@ import {normalizeUrl, parseUrl} from './utils';
const EMPTY_SERVER_STATE = new MockServerStateBuilder().build();
export class SwTestHarnessBuilder {
private origin = parseUrl(this.scopeUrl).origin;
private origin: string;
private server = EMPTY_SERVER_STATE;
private caches = new MockCacheStorage(this.origin);
private caches: MockCacheStorage;
constructor(private scopeUrl = 'http://localhost/') {}
constructor(private scopeUrl = 'http://localhost/') {
this.origin = parseUrl(this.scopeUrl).origin;
this.caches = new MockCacheStorage(this.origin);
}
withCacheState(cache: string): SwTestHarnessBuilder {
this.caches = new MockCacheStorage(this.origin, cache);
-2
View File
@@ -19,8 +19,6 @@
"moduleResolution": "node",
"module": "esnext",
"target": "es2022",
// Keep the below in sync with ng_module.bzl
"useDefineForClassFields": false,
"lib": ["es2020", "dom", "dom.iterable"],
"skipLibCheck": true,
// don't auto-discover @types/node, it results in a ///<reference in the .d.ts output
@@ -59,11 +59,7 @@ export class SaucelabsDaemon {
/** Map that contains test ids with their claimed browser. */
private _runningTests = new Map<number, RemoteBrowser>();
/** Server used for communication with the Karma launcher. */
private _server = new IpcServer(this);
/** Base selenium capabilities that will be added to each browser. */
private _baseCapabilities = {...defaultCapabilities, ...this._userCapabilities};
private _baseCapabilities;
/** Id of the keep alive interval that ensures no remote browsers time out. */
private _keepAliveIntervalId: NodeJS.Timeout | null = null;
@@ -85,6 +81,9 @@ export class SaucelabsDaemon {
) {
// Starts the keep alive loop for all active browsers, running every 15 seconds.
this._keepAliveIntervalId = setInterval(() => this._keepAliveBrowsers(), 15_000);
/** Base selenium capabilities that will be added to each browser. */
this._baseCapabilities = {...defaultCapabilities, ...this._userCapabilities};
}
/**