build: support building with TypeScript 4.1 (#39571)
TypeScript 4.1 is now used to build and test within the repository. PR Close #39571
This commit is contained in:
parent
a7e7c211b5
commit
318255a5f8
|
@ -49,6 +49,6 @@
|
||||||
"supertest": "^4.0.2",
|
"supertest": "^4.0.2",
|
||||||
"tslint": "^6.1.3",
|
"tslint": "^6.1.3",
|
||||||
"tslint-jasmine-noSkipOrFocus": "^1.0.9",
|
"tslint-jasmine-noSkipOrFocus": "^1.0.9",
|
||||||
"typescript": "^4.0.2"
|
"typescript": "^4.1.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2563,10 +2563,10 @@ typedarray-to-buffer@^3.1.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-typedarray "^1.0.0"
|
is-typedarray "^1.0.0"
|
||||||
|
|
||||||
typescript@^4.0.2:
|
typescript@^4.1.2:
|
||||||
version "4.0.2"
|
version "4.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.2.tgz#7ea7c88777c723c681e33bf7988be5d008d05ac2"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.2.tgz#6369ef22516fe5e10304aae5a5c4862db55380e9"
|
||||||
integrity sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==
|
integrity sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ==
|
||||||
|
|
||||||
undefsafe@^2.0.2:
|
undefsafe@^2.0.2:
|
||||||
version "2.0.2"
|
version "2.0.2"
|
||||||
|
|
|
@ -304,6 +304,6 @@ class FakeModuleFactory extends NgModuleFactory<any> {
|
||||||
|
|
||||||
function returnPromisesFromSpy(spy: jasmine.Spy): Deferred[] {
|
function returnPromisesFromSpy(spy: jasmine.Spy): Deferred[] {
|
||||||
const deferreds: Deferred[] = [];
|
const deferreds: Deferred[] = [];
|
||||||
spy.and.callFake(() => new Promise((resolve, reject) => deferreds.push({resolve, reject})));
|
spy.and.callFake(() => new Promise<void>((resolve, reject) => deferreds.push({resolve, reject})));
|
||||||
return deferreds;
|
return deferreds;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13658,7 +13658,7 @@ typedarray@^0.0.6:
|
||||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||||
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
||||||
|
|
||||||
typescript@4.0.5:
|
typescript@4.0.5, typescript@~4.0.2:
|
||||||
version "4.0.5"
|
version "4.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.5.tgz#ae9dddfd1069f1cb5beb3ef3b2170dd7c1332389"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.5.tgz#ae9dddfd1069f1cb5beb3ef3b2170dd7c1332389"
|
||||||
integrity sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==
|
integrity sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==
|
||||||
|
@ -13668,11 +13668,6 @@ typescript@^3.2.2:
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.5.tgz#0692e21f65fd4108b9330238aac11dd2e177a1ae"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.5.tgz#0692e21f65fd4108b9330238aac11dd2e177a1ae"
|
||||||
integrity sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==
|
integrity sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==
|
||||||
|
|
||||||
typescript@~4.0.2:
|
|
||||||
version "4.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.3.tgz#153bbd468ef07725c1df9c77e8b453f8d36abba5"
|
|
||||||
integrity sha512-tEu6DGxGgRJPb/mVPIZ48e69xCn2yRmCgYmDugAVwmJ6o+0u1RI18eO7E7WBTLYLaEVVOhwQmcdhQHweux/WPg==
|
|
||||||
|
|
||||||
ua-parser-js@0.7.21:
|
ua-parser-js@0.7.21:
|
||||||
version "0.7.21"
|
version "0.7.21"
|
||||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.21.tgz#853cf9ce93f642f67174273cc34565ae6f308777"
|
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.21.tgz#853cf9ce93f642f67174273cc34565ae6f308777"
|
||||||
|
|
|
@ -18,8 +18,8 @@ export abstract class BaseModule<Data> {
|
||||||
protected git: GitClient, protected config: NgDevConfig<{caretaker: CaretakerConfig}>) {}
|
protected git: GitClient, protected config: NgDevConfig<{caretaker: CaretakerConfig}>) {}
|
||||||
|
|
||||||
/** Asyncronously retrieve data for the module. */
|
/** Asyncronously retrieve data for the module. */
|
||||||
protected abstract async retrieveData(): Promise<Data>;
|
protected abstract retrieveData(): Promise<Data>;
|
||||||
|
|
||||||
/** Print the information discovered for the module to the terminal. */
|
/** Print the information discovered for the module to the terminal. */
|
||||||
abstract async printToTerminal(): Promise<void>;
|
abstract printToTerminal(): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ export async function execTimed(description: string, func: () => Promise<void>)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function nextTick(delay = 1) {
|
export async function nextTick(delay = 1) {
|
||||||
return new Promise((res, rej) => {
|
return new Promise<void>((res, rej) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
res();
|
res();
|
||||||
}, delay);
|
}, delay);
|
||||||
|
|
|
@ -150,7 +150,7 @@
|
||||||
"tsickle": "0.38.1",
|
"tsickle": "0.38.1",
|
||||||
"tslib": "^2.0.0",
|
"tslib": "^2.0.0",
|
||||||
"tslint": "6.1.3",
|
"tslint": "6.1.3",
|
||||||
"typescript": "~4.0.2",
|
"typescript": "~4.1.2",
|
||||||
"xhr2": "0.2.0",
|
"xhr2": "0.2.0",
|
||||||
"yaml": "^1.10.0",
|
"yaml": "^1.10.0",
|
||||||
"yargs": "^16.1.1"
|
"yargs": "^16.1.1"
|
||||||
|
|
|
@ -810,7 +810,7 @@ export class TransitionAnimationEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
whenRenderingDone(): Promise<any> {
|
whenRenderingDone(): Promise<any> {
|
||||||
return new Promise(resolve => {
|
return new Promise<void>(resolve => {
|
||||||
if (this.players.length) {
|
if (this.players.length) {
|
||||||
return optimizeGroupPlayer(this.players).onDone(() => resolve());
|
return optimizeGroupPlayer(this.players).onDone(() => resolve());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
"@angular/compiler-cli": "0.0.0-PLACEHOLDER",
|
"@angular/compiler-cli": "0.0.0-PLACEHOLDER",
|
||||||
"@bazel/typescript": ">=1.0.0",
|
"@bazel/typescript": ">=1.0.0",
|
||||||
"terser": "^4.3.1",
|
"terser": "^4.3.1",
|
||||||
"typescript": ">=4.0 <4.1",
|
"typescript": ">=4.0 <4.2",
|
||||||
"rollup": ">=1.20.0",
|
"rollup": ">=1.20.0",
|
||||||
"rollup-plugin-commonjs": ">=9.0.0",
|
"rollup-plugin-commonjs": ">=9.0.0",
|
||||||
"rollup-plugin-node-resolve": ">=4.2.0",
|
"rollup-plugin-node-resolve": ">=4.2.0",
|
||||||
|
|
|
@ -43,7 +43,7 @@ export class Options {
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeFile(filename: string, content: string): Promise<any> {
|
function writeFile(filename: string, content: string): Promise<any> {
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise<void>(function(resolve, reject) {
|
||||||
fs.writeFile(filename, content, (error) => {
|
fs.writeFile(filename, content, (error) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
reject(error);
|
reject(error);
|
||||||
|
|
|
@ -78,7 +78,7 @@ export function findNamespaceOfIdentifier(id: ts.Identifier): ts.Identifier|null
|
||||||
export function findRequireCallReference(id: ts.Identifier, checker: ts.TypeChecker): RequireCall|
|
export function findRequireCallReference(id: ts.Identifier, checker: ts.TypeChecker): RequireCall|
|
||||||
null {
|
null {
|
||||||
const symbol = checker.getSymbolAtLocation(id) || null;
|
const symbol = checker.getSymbolAtLocation(id) || null;
|
||||||
const declaration = symbol && symbol.valueDeclaration;
|
const declaration = symbol?.valueDeclaration ?? symbol?.declarations?.[0];
|
||||||
const initializer =
|
const initializer =
|
||||||
declaration && ts.isVariableDeclaration(declaration) && declaration.initializer || null;
|
declaration && ts.isVariableDeclaration(declaration) && declaration.initializer || null;
|
||||||
return initializer && isRequireCall(initializer) ? initializer : null;
|
return initializer && isRequireCall(initializer) ? initializer : null;
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@angular/compiler": "0.0.0-PLACEHOLDER",
|
"@angular/compiler": "0.0.0-PLACEHOLDER",
|
||||||
"typescript": ">=4.0 <4.1"
|
"typescript": ">=4.0 <4.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.0"
|
"node": ">=10.0"
|
||||||
|
|
|
@ -126,9 +126,9 @@ enum TsStructureIsReused {
|
||||||
Completely = 2,
|
Completely = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
export function expectCompleteReuse(oldProgram: ts.Program): void {
|
export function expectCompleteReuse(program: ts.Program): void {
|
||||||
// Assert complete reuse using TypeScript's private API.
|
// Assert complete reuse using TypeScript's private API.
|
||||||
expect((oldProgram as any).structureIsReused)
|
expect((program as any).structureIsReused)
|
||||||
.toBe(TsStructureIsReused.Completely, COMPLETE_REUSE_FAILURE_MESSAGE);
|
.toBe(TsStructureIsReused.Completely, COMPLETE_REUSE_FAILURE_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ runInEachFileSystem(() => {
|
||||||
programStrategy.updateFiles(
|
programStrategy.updateFiles(
|
||||||
new Map([[typecheckPath, 'export const VERSION = 2;']]), UpdateMode.Complete);
|
new Map([[typecheckPath, 'export const VERSION = 2;']]), UpdateMode.Complete);
|
||||||
|
|
||||||
expectCompleteReuse(program);
|
expectCompleteReuse(programStrategy.getProgram());
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have complete reuse if no structural changes are made to input files', () => {
|
it('should have complete reuse if no structural changes are made to input files', () => {
|
||||||
|
@ -56,7 +56,7 @@ runInEachFileSystem(() => {
|
||||||
programStrategy.updateFiles(
|
programStrategy.updateFiles(
|
||||||
new Map([[mainPath, 'export const STILL_NOT_A_COMPONENT = true;']]), UpdateMode.Complete);
|
new Map([[mainPath, 'export const STILL_NOT_A_COMPONENT = true;']]), UpdateMode.Complete);
|
||||||
|
|
||||||
expectCompleteReuse(program);
|
expectCompleteReuse(programStrategy.getProgram());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -127,7 +127,7 @@ export function performWatchCompilation(host: PerformWatchHost):
|
||||||
|
|
||||||
// Watch basePath, ignoring .dotfiles
|
// Watch basePath, ignoring .dotfiles
|
||||||
let resolveReadyPromise: () => void;
|
let resolveReadyPromise: () => void;
|
||||||
const readyPromise = new Promise(resolve => resolveReadyPromise = resolve);
|
const readyPromise = new Promise<void>(resolve => resolveReadyPromise = resolve);
|
||||||
// Note: ! is ok as options are filled after the first compilation
|
// Note: ! is ok as options are filled after the first compilation
|
||||||
// Note: ! is ok as resolvedReadyPromise is filled by the previous call
|
// Note: ! is ok as resolvedReadyPromise is filled by the previous call
|
||||||
const fileWatcher =
|
const fileWatcher =
|
||||||
|
|
|
@ -48,6 +48,17 @@ const LOWER_FIELDS = ['useValue', 'useFactory', 'data', 'id', 'loadChildren'];
|
||||||
*/
|
*/
|
||||||
const R3_LOWER_FIELDS = [...LOWER_FIELDS, 'providers', 'imports', 'exports'];
|
const R3_LOWER_FIELDS = [...LOWER_FIELDS, 'providers', 'imports', 'exports'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Installs a handler for testing purposes to allow inspection of the temporary program.
|
||||||
|
*/
|
||||||
|
let tempProgramHandlerForTest: ((program: ts.Program) => void)|null = null;
|
||||||
|
export function setTempProgramHandlerForTest(handler: (program: ts.Program) => void): void {
|
||||||
|
tempProgramHandlerForTest = handler;
|
||||||
|
}
|
||||||
|
export function resetTempProgramHandlerForTest(): void {
|
||||||
|
tempProgramHandlerForTest = null;
|
||||||
|
}
|
||||||
|
|
||||||
const emptyModules: NgAnalyzedModules = {
|
const emptyModules: NgAnalyzedModules = {
|
||||||
ngModules: [],
|
ngModules: [],
|
||||||
ngModuleByPipeOrDirective: new Map(),
|
ngModuleByPipeOrDirective: new Map(),
|
||||||
|
@ -618,6 +629,9 @@ class AngularCompilerProgram implements Program {
|
||||||
}
|
}
|
||||||
|
|
||||||
const tmpProgram = ts.createProgram(rootNames, this.options, this.hostAdapter, oldTsProgram);
|
const tmpProgram = ts.createProgram(rootNames, this.options, this.hostAdapter, oldTsProgram);
|
||||||
|
if (tempProgramHandlerForTest !== null) {
|
||||||
|
tempProgramHandlerForTest(tmpProgram);
|
||||||
|
}
|
||||||
const sourceFiles: string[] = [];
|
const sourceFiles: string[] = [];
|
||||||
const tsFiles: string[] = [];
|
const tsFiles: string[] = [];
|
||||||
tmpProgram.getSourceFiles().forEach(sf => {
|
tmpProgram.getSourceFiles().forEach(sf => {
|
||||||
|
|
|
@ -1671,7 +1671,7 @@ describe('ngc transformer command-line', () => {
|
||||||
const config = readCommandLineAndConfiguration(['-p', basePath]);
|
const config = readCommandLineAndConfiguration(['-p', basePath]);
|
||||||
const compile = watchMode(config.project, config.options, errorSpy);
|
const compile = watchMode(config.project, config.options, errorSpy);
|
||||||
|
|
||||||
return new Promise(resolve => {
|
return new Promise<void>(resolve => {
|
||||||
compile.ready(() => {
|
compile.ready(() => {
|
||||||
cb();
|
cb();
|
||||||
|
|
||||||
|
|
|
@ -358,7 +358,7 @@ export declare class AnimationEvent {
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'test',
|
selector: 'test',
|
||||||
template: '<div dir [foo]="invalid && 1"></div>',
|
template: '<div dir [foo]="!!invalid"></div>',
|
||||||
})
|
})
|
||||||
class TestCmp {}
|
class TestCmp {}
|
||||||
|
|
||||||
|
@ -379,7 +379,7 @@ export declare class AnimationEvent {
|
||||||
|
|
||||||
const diags = env.driveDiagnostics();
|
const diags = env.driveDiagnostics();
|
||||||
expect(diags.length).toBe(2);
|
expect(diags.length).toBe(2);
|
||||||
expect(diags[0].messageText).toEqual(`Type 'number' is not assignable to type 'string'.`);
|
expect(diags[0].messageText).toEqual(`Type 'boolean' is not assignable to type 'string'.`);
|
||||||
expect(diags[1].messageText)
|
expect(diags[1].messageText)
|
||||||
.toEqual(`Property 'invalid' does not exist on type 'TestCmp'.`);
|
.toEqual(`Property 'invalid' does not exist on type 'TestCmp'.`);
|
||||||
});
|
});
|
||||||
|
@ -389,7 +389,7 @@ export declare class AnimationEvent {
|
||||||
|
|
||||||
const diags = env.driveDiagnostics();
|
const diags = env.driveDiagnostics();
|
||||||
expect(diags.length).toBe(2);
|
expect(diags.length).toBe(2);
|
||||||
expect(diags[0].messageText).toEqual(`Type 'number' is not assignable to type 'string'.`);
|
expect(diags[0].messageText).toEqual(`Type 'boolean' is not assignable to type 'string'.`);
|
||||||
expect(diags[1].messageText)
|
expect(diags[1].messageText)
|
||||||
.toEqual(`Property 'invalid' does not exist on type 'TestCmp'.`);
|
.toEqual(`Property 'invalid' does not exist on type 'TestCmp'.`);
|
||||||
});
|
});
|
||||||
|
@ -411,15 +411,15 @@ export declare class AnimationEvent {
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'test',
|
selector: 'test',
|
||||||
template: '<div dir [foo]="invalid && nullable"></div>',
|
template: '<div dir [foo]="!!invalid && nullable"></div>',
|
||||||
})
|
})
|
||||||
class TestCmp {
|
class TestCmp {
|
||||||
nullable: string | null | undefined;
|
nullable: boolean | null | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Directive({selector: '[dir]'})
|
@Directive({selector: '[dir]'})
|
||||||
class TestDir {
|
class TestDir {
|
||||||
@Input() foo: string;
|
@Input() foo: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
@ -436,7 +436,7 @@ export declare class AnimationEvent {
|
||||||
const diags = env.driveDiagnostics();
|
const diags = env.driveDiagnostics();
|
||||||
expect(diags.length).toBe(2);
|
expect(diags.length).toBe(2);
|
||||||
expect((diags[0].messageText as ts.DiagnosticMessageChain).messageText)
|
expect((diags[0].messageText as ts.DiagnosticMessageChain).messageText)
|
||||||
.toEqual(`Type 'string | null | undefined' is not assignable to type 'string'.`);
|
.toEqual(`Type 'boolean | null | undefined' is not assignable to type 'boolean'.`);
|
||||||
expect(diags[1].messageText)
|
expect(diags[1].messageText)
|
||||||
.toEqual(`Property 'invalid' does not exist on type 'TestCmp'.`);
|
.toEqual(`Property 'invalid' does not exist on type 'TestCmp'.`);
|
||||||
});
|
});
|
||||||
|
@ -448,7 +448,7 @@ export declare class AnimationEvent {
|
||||||
const diags = env.driveDiagnostics();
|
const diags = env.driveDiagnostics();
|
||||||
expect(diags.length).toBe(2);
|
expect(diags.length).toBe(2);
|
||||||
expect((diags[0].messageText as ts.DiagnosticMessageChain).messageText)
|
expect((diags[0].messageText as ts.DiagnosticMessageChain).messageText)
|
||||||
.toEqual(`Type 'string | null | undefined' is not assignable to type 'string'.`);
|
.toEqual(`Type 'boolean | null | undefined' is not assignable to type 'boolean'.`);
|
||||||
expect(diags[1].messageText)
|
expect(diags[1].messageText)
|
||||||
.toEqual(`Property 'invalid' does not exist on type 'TestCmp'.`);
|
.toEqual(`Property 'invalid' does not exist on type 'TestCmp'.`);
|
||||||
});
|
});
|
||||||
|
@ -470,15 +470,15 @@ export declare class AnimationEvent {
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'test',
|
selector: 'test',
|
||||||
template: '<div dir [foo]="invalid && user?.name"></div>',
|
template: '<div dir [foo]="!!invalid && user?.isMember"></div>',
|
||||||
})
|
})
|
||||||
class TestCmp {
|
class TestCmp {
|
||||||
user?: {name: string};
|
user?: {isMember: boolean};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Directive({selector: '[dir]'})
|
@Directive({selector: '[dir]'})
|
||||||
class TestDir {
|
class TestDir {
|
||||||
@Input() foo: string;
|
@Input() foo: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
@ -499,7 +499,7 @@ export declare class AnimationEvent {
|
||||||
const diags = env.driveDiagnostics();
|
const diags = env.driveDiagnostics();
|
||||||
expect(diags.length).toBe(2);
|
expect(diags.length).toBe(2);
|
||||||
expect((diags[0].messageText as ts.DiagnosticMessageChain).messageText)
|
expect((diags[0].messageText as ts.DiagnosticMessageChain).messageText)
|
||||||
.toEqual(`Type 'string | undefined' is not assignable to type 'string'.`);
|
.toEqual(`Type 'boolean | undefined' is not assignable to type 'boolean'.`);
|
||||||
expect(diags[1].messageText)
|
expect(diags[1].messageText)
|
||||||
.toEqual(`Property 'invalid' does not exist on type 'TestCmp'.`);
|
.toEqual(`Property 'invalid' does not exist on type 'TestCmp'.`);
|
||||||
});
|
});
|
||||||
|
@ -511,7 +511,7 @@ export declare class AnimationEvent {
|
||||||
const diags = env.driveDiagnostics();
|
const diags = env.driveDiagnostics();
|
||||||
expect(diags.length).toBe(2);
|
expect(diags.length).toBe(2);
|
||||||
expect((diags[0].messageText as ts.DiagnosticMessageChain).messageText)
|
expect((diags[0].messageText as ts.DiagnosticMessageChain).messageText)
|
||||||
.toEqual(`Type 'string | undefined' is not assignable to type 'string'.`);
|
.toEqual(`Type 'boolean | undefined' is not assignable to type 'boolean'.`);
|
||||||
expect(diags[1].messageText)
|
expect(diags[1].messageText)
|
||||||
.toEqual(`Property 'invalid' does not exist on type 'TestCmp'.`);
|
.toEqual(`Property 'invalid' does not exist on type 'TestCmp'.`);
|
||||||
});
|
});
|
||||||
|
@ -2325,7 +2325,8 @@ export declare class AnimationEvent {
|
||||||
env.write('other.ts', `export const VERSION = 2;`);
|
env.write('other.ts', `export const VERSION = 2;`);
|
||||||
env.driveMain();
|
env.driveMain();
|
||||||
|
|
||||||
expectCompleteReuse(firstProgram);
|
expectCompleteReuse(env.getTsProgram());
|
||||||
|
expectCompleteReuse(env.getReuseTsProgram());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,7 +13,7 @@ import * as ts from 'typescript';
|
||||||
|
|
||||||
import {formatDiagnostics} from '../../src/perform_compile';
|
import {formatDiagnostics} from '../../src/perform_compile';
|
||||||
import {CompilerHost, EmitFlags, LazyRoute} from '../../src/transformers/api';
|
import {CompilerHost, EmitFlags, LazyRoute} from '../../src/transformers/api';
|
||||||
import {createSrcToOutPathMapper} from '../../src/transformers/program';
|
import {createSrcToOutPathMapper, resetTempProgramHandlerForTest, setTempProgramHandlerForTest} from '../../src/transformers/program';
|
||||||
import {StructureIsReused, tsStructureIsReused} from '../../src/transformers/util';
|
import {StructureIsReused, tsStructureIsReused} from '../../src/transformers/util';
|
||||||
import {expectNoDiagnosticsInProgram, setup, stripAnsi, TestSupport} from '../test_support';
|
import {expectNoDiagnosticsInProgram, setup, stripAnsi, TestSupport} from '../test_support';
|
||||||
|
|
||||||
|
@ -297,6 +297,17 @@ describe('ng program', () => {
|
||||||
describe(
|
describe(
|
||||||
'verify that program structure is reused within tsc in order to speed up incremental compilation',
|
'verify that program structure is reused within tsc in order to speed up incremental compilation',
|
||||||
() => {
|
() => {
|
||||||
|
afterEach(resetTempProgramHandlerForTest);
|
||||||
|
|
||||||
|
function captureStructureReuse(compile: () => void): StructureIsReused|null {
|
||||||
|
let structureReuse: StructureIsReused|null = null;
|
||||||
|
setTempProgramHandlerForTest(program => {
|
||||||
|
structureReuse = tsStructureIsReused(program);
|
||||||
|
});
|
||||||
|
compile();
|
||||||
|
return structureReuse;
|
||||||
|
}
|
||||||
|
|
||||||
it('should reuse the old ts program completely if nothing changed', () => {
|
it('should reuse the old ts program completely if nothing changed', () => {
|
||||||
testSupport.writeFiles({'src/index.ts': createModuleAndCompSource('main')});
|
testSupport.writeFiles({'src/index.ts': createModuleAndCompSource('main')});
|
||||||
const host = createWatchModeHost();
|
const host = createWatchModeHost();
|
||||||
|
@ -304,8 +315,9 @@ describe('ng program', () => {
|
||||||
// and therefore changes the structure again
|
// and therefore changes the structure again
|
||||||
const p1 = compile(undefined, undefined, undefined, host).program;
|
const p1 = compile(undefined, undefined, undefined, host).program;
|
||||||
const p2 = compile(p1, undefined, undefined, host).program;
|
const p2 = compile(p1, undefined, undefined, host).program;
|
||||||
compile(p2, undefined, undefined, host);
|
const structureReuse =
|
||||||
expect(tsStructureIsReused(p2.getTsProgram())).toBe(StructureIsReused.Completely);
|
captureStructureReuse(() => compile(p2, undefined, undefined, host));
|
||||||
|
expect(structureReuse).toBe(StructureIsReused.Completely);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should reuse the old ts program completely if a template or a ts file changed',
|
it('should reuse the old ts program completely if a template or a ts file changed',
|
||||||
|
@ -328,8 +340,9 @@ describe('ng program', () => {
|
||||||
'src/main.html': `Another template`,
|
'src/main.html': `Another template`,
|
||||||
'src/util.ts': `export const x = 2`,
|
'src/util.ts': `export const x = 2`,
|
||||||
});
|
});
|
||||||
compile(p2, undefined, undefined, host);
|
const structureReuse =
|
||||||
expect(tsStructureIsReused(p2.getTsProgram())).toBe(StructureIsReused.Completely);
|
captureStructureReuse(() => compile(p2, undefined, undefined, host));
|
||||||
|
expect(structureReuse).toBe(StructureIsReused.Completely);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not reuse the old ts program if an import changed', () => {
|
it('should not reuse the old ts program if an import changed', () => {
|
||||||
|
@ -348,8 +361,9 @@ describe('ng program', () => {
|
||||||
const p2 = compile(p1, undefined, undefined, host).program;
|
const p2 = compile(p1, undefined, undefined, host).program;
|
||||||
testSupport.writeFiles(
|
testSupport.writeFiles(
|
||||||
{'src/util.ts': `import {Injectable} from '@angular/core'; export const x = 1;`});
|
{'src/util.ts': `import {Injectable} from '@angular/core'; export const x = 1;`});
|
||||||
compile(p2, undefined, undefined, host);
|
const structureReuse =
|
||||||
expect(tsStructureIsReused(p2.getTsProgram())).toBe(StructureIsReused.SafeModules);
|
captureStructureReuse(() => compile(p2, undefined, undefined, host));
|
||||||
|
expect(structureReuse).toBe(StructureIsReused.SafeModules);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1048,7 +1048,7 @@ function expectParseTemplateBindingsError(attribute: string, error: string) {
|
||||||
function _parseTemplateBindings(attribute: string, templateUrl: string) {
|
function _parseTemplateBindings(attribute: string, templateUrl: string) {
|
||||||
const match = attribute.match(/^\*(.+)="(.*)"$/);
|
const match = attribute.match(/^\*(.+)="(.*)"$/);
|
||||||
expect(match).toBeTruthy(`failed to extract key and value from ${attribute}`);
|
expect(match).toBeTruthy(`failed to extract key and value from ${attribute}`);
|
||||||
const [_, key, value] = match;
|
const [_, key, value] = match!;
|
||||||
const absKeyOffset = 1; // skip the * prefix
|
const absKeyOffset = 1; // skip the * prefix
|
||||||
const absValueOffset = attribute.indexOf('=') + '="'.length;
|
const absValueOffset = attribute.indexOf('=') + '="'.length;
|
||||||
const parser = createParser();
|
const parser = createParser();
|
||||||
|
|
|
@ -53,7 +53,7 @@ function getMetaRenderHook(doc: any) {
|
||||||
function getAsyncTitleRenderHook(doc: any) {
|
function getAsyncTitleRenderHook(doc: any) {
|
||||||
return () => {
|
return () => {
|
||||||
// Async set the title as part of the render hook.
|
// Async set the title as part of the render hook.
|
||||||
return new Promise(resolve => {
|
return new Promise<void>(resolve => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
doc.title = 'AsyncRenderHook';
|
doc.title = 'AsyncRenderHook';
|
||||||
resolve();
|
resolve();
|
||||||
|
@ -64,7 +64,7 @@ function getAsyncTitleRenderHook(doc: any) {
|
||||||
|
|
||||||
function asyncRejectRenderHook() {
|
function asyncRejectRenderHook() {
|
||||||
return () => {
|
return () => {
|
||||||
return new Promise((_resolve, reject) => {
|
return new Promise<void>((_resolve, reject) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
reject('reject');
|
reject('reject');
|
||||||
});
|
});
|
||||||
|
|
|
@ -97,7 +97,7 @@ export function validateInjectionKey(
|
||||||
export class Deferred<R> {
|
export class Deferred<R> {
|
||||||
promise: Promise<R>;
|
promise: Promise<R>;
|
||||||
// TODO(issue/24571): remove '!'.
|
// TODO(issue/24571): remove '!'.
|
||||||
resolve!: (value?: R|PromiseLike<R>) => void;
|
resolve!: (value: R|PromiseLike<R>) => void;
|
||||||
// TODO(issue/24571): remove '!'.
|
// TODO(issue/24571): remove '!'.
|
||||||
reject!: (error?: any) => void;
|
reject!: (error?: any) => void;
|
||||||
|
|
||||||
|
|
|
@ -396,7 +396,7 @@ export class UpgradeAdapter {
|
||||||
this.ngZone.run(() => {
|
this.ngZone.run(() => {
|
||||||
bootstrap(element, [this.ng1Module.name], config!);
|
bootstrap(element, [this.ng1Module.name], config!);
|
||||||
});
|
});
|
||||||
const ng1BootstrapPromise = new Promise((resolve) => {
|
const ng1BootstrapPromise = new Promise<void>((resolve) => {
|
||||||
if (windowAngular.resumeBootstrap) {
|
if (windowAngular.resumeBootstrap) {
|
||||||
const originalResumeBootstrap: () => void = windowAngular.resumeBootstrap;
|
const originalResumeBootstrap: () => void = windowAngular.resumeBootstrap;
|
||||||
windowAngular.resumeBootstrap = function() {
|
windowAngular.resumeBootstrap = function() {
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
"mocha": "^3.1.2",
|
"mocha": "^3.1.2",
|
||||||
"mock-require": "3.0.3",
|
"mock-require": "3.0.3",
|
||||||
"promises-aplus-tests": "^2.1.2",
|
"promises-aplus-tests": "^2.1.2",
|
||||||
"typescript": "4.0.2"
|
"typescript": "4.1.2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"closuretest": "./scripts/closure/closure_compiler.sh",
|
"closuretest": "./scripts/closure/closure_compiler.sh",
|
||||||
|
|
|
@ -65,7 +65,7 @@ ifEnvSupports(supportJasmineSpec, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should wait for promise to resolve', () => {
|
it('should wait for promise to resolve', () => {
|
||||||
return new Promise((res, _) => {
|
return new Promise<void>((res, _) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
log.push('resolved');
|
log.push('resolved');
|
||||||
res();
|
res();
|
||||||
|
|
|
@ -103,7 +103,7 @@ ifEnvSupports('Mocha', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should wait for promise to resolve', () => {
|
it('should wait for promise to resolve', () => {
|
||||||
return new Promise((res, _) => {
|
return new Promise<void>((res, _) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
log.push('resolved');
|
log.push('resolved');
|
||||||
res();
|
res();
|
||||||
|
|
|
@ -14,6 +14,6 @@
|
||||||
"zone.js": "file:../../../../dist/bin/packages/zone.js/npm_package"
|
"zone.js": "file:../../../../dist/bin/packages/zone.js/npm_package"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "~4.0.2"
|
"typescript": "~4.1.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ describe('AsyncTestZoneSpec', function() {
|
||||||
const atz = Zone.current.fork(testZoneSpec);
|
const atz = Zone.current.fork(testZoneSpec);
|
||||||
|
|
||||||
atz.run(function() {
|
atz.run(function() {
|
||||||
new Promise((resolve) => {
|
new Promise<void>((resolve) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
resolve();
|
resolve();
|
||||||
}, 10);
|
}, 10);
|
||||||
|
|
|
@ -942,7 +942,7 @@ describe('FakeAsyncTestZoneSpec', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should wait for promise to resolve', () => {
|
it('should wait for promise to resolve', () => {
|
||||||
return new Promise((res, _) => {
|
return new Promise<void>((res, _) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
log.push('resolved');
|
log.push('resolved');
|
||||||
res();
|
res();
|
||||||
|
|
|
@ -3786,10 +3786,10 @@ typedarray-to-buffer@^3.1.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-typedarray "^1.0.0"
|
is-typedarray "^1.0.0"
|
||||||
|
|
||||||
typescript@4.0.2:
|
typescript@4.1.2:
|
||||||
version "4.0.2"
|
version "4.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.2.tgz#7ea7c88777c723c681e33bf7988be5d008d05ac2"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.2.tgz#6369ef22516fe5e10304aae5a5c4862db55380e9"
|
||||||
integrity sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==
|
integrity sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ==
|
||||||
|
|
||||||
underscore@~1.8.3:
|
underscore@~1.8.3:
|
||||||
version "1.8.3"
|
version "1.8.3"
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
"chai": "^4.1.2",
|
"chai": "^4.1.2",
|
||||||
"jasmine": "^3.1.0",
|
"jasmine": "^3.1.0",
|
||||||
"source-map-support": "^0.5.9",
|
"source-map-support": "^0.5.9",
|
||||||
"typescript": "4.0.2"
|
"typescript": "4.1.2"
|
||||||
},
|
},
|
||||||
"repository": {},
|
"repository": {},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -51,4 +51,4 @@
|
||||||
"url": "https://github.com/angular/angular/issues"
|
"url": "https://github.com/angular/angular/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/angular/angular/tools/ts-api-guardian"
|
"homepage": "https://github.com/angular/angular/tools/ts-api-guardian"
|
||||||
}
|
}
|
||||||
|
|
|
@ -15621,10 +15621,10 @@ typescript@~3.7.2:
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.5.tgz#0692e21f65fd4108b9330238aac11dd2e177a1ae"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.5.tgz#0692e21f65fd4108b9330238aac11dd2e177a1ae"
|
||||||
integrity sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==
|
integrity sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==
|
||||||
|
|
||||||
typescript@~4.0.2:
|
typescript@~4.1.2:
|
||||||
version "4.0.2"
|
version "4.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.2.tgz#7ea7c88777c723c681e33bf7988be5d008d05ac2"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.2.tgz#6369ef22516fe5e10304aae5a5c4862db55380e9"
|
||||||
integrity sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==
|
integrity sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ==
|
||||||
|
|
||||||
uglify-js@^1.3.3:
|
uglify-js@^1.3.3:
|
||||||
version "1.3.5"
|
version "1.3.5"
|
||||||
|
|
Loading…
Reference in New Issue