refactor: update angular to support TypeScript 2.4

Detailed updates:
- rxjs@5.0.x
- tsickle@0.24.x
- typescript@2.4.x
- @bazel/typescript@0.10.0
- protractor@5.1.x
- selenium-webdriver@3.0.x

BREAKING CHANGE:
- the Angular compiler now requires TypeScript 2.4.x.
This commit is contained in:
Tobias Bosch
2017-09-08 18:40:32 -07:00
committed by Matias Niemelä
parent 112e777b90
commit ca5aebaa6b
49 changed files with 429 additions and 363 deletions

View File

@ -11,9 +11,9 @@
"license": "MIT",
"repository": {"type":"git","url":"https://github.com/angular/angular.git"},
"dependencies": {
"tsickle": "^0.23.5"
"tsickle": "^0.24.0"
},
"peerDependencies": {
"typescript": "^2.1.5"
"typescript": "^2.4.2"
}
}

View File

@ -54,6 +54,9 @@ export function main(
if (diagnostics) (ts as any).performance.enable();
let host = ts.createCompilerHost(parsed.options, true);
// Make sure we do not `host.realpath()` from TS as we do not want to resolve symlinks.
// https://github.com/Microsoft/TypeScript/issues/9552
host.realpath = (fileName: string) => fileName;
// If the compilation is a flat module index then produce the flat module index
// metadata and the synthetic flat module index.
@ -65,20 +68,19 @@ export function main(
host = bundleHost;
}
const tsickleCompilerHostOptions:
tsickle.Options = {googmodule: false, untyped: true, convertIndexImportShorthand: false};
const tsickleHost: tsickle.TsickleHost = {
shouldSkipTsickleProcessing: (fileName) => /\.d\.ts$/.test(fileName),
pathToModuleName: (context, importPath) => '',
shouldIgnoreWarningsForPath: (filePath) => false,
fileNameToModuleId: (fileName) => fileName,
googmodule: false,
untyped: true,
convertIndexImportShorthand: false,
transformDecorators: ngOptions.annotationsAs !== 'decorators',
transformTypesToClosure: ngOptions.annotateForClosureCompiler,
};
const tsickleCompilerHost =
new tsickle.TsickleCompilerHost(host, ngOptions, tsickleCompilerHostOptions, tsickleHost);
const program = createProgram(tsickleCompilerHost);
const program = createProgram(host);
const errors = program.getOptionsDiagnostics();
check(errors);
@ -95,48 +97,19 @@ export function main(
if (ngOptions.alwaysCompileGeneratedCode) {
genFiles.forEach(genFileName => addGeneratedFileName(genFileName));
}
let definitionsHost: ts.CompilerHost = tsickleCompilerHost;
if (!ngOptions.skipMetadataEmit) {
// if tsickle is not not used for emitting, but we do use the MetadataWriterHost,
// it also needs to emit the js files.
const emitJsFiles =
ngOptions.annotationsAs === 'decorators' && !ngOptions.annotateForClosureCompiler;
definitionsHost = new MetadataWriterHost(tsickleCompilerHost, ngOptions, emitJsFiles);
host = new MetadataWriterHost(host, ngOptions, true);
}
// Create a new program since codegen files were created after making the old program
let programWithCodegen = createProgram(definitionsHost, program);
let programWithCodegen = createProgram(host, program);
tsc.typeCheck(host, programWithCodegen);
let programForJsEmit = programWithCodegen;
if (ngOptions.annotationsAs !== 'decorators') {
if (diagnostics) console.time('NG downlevel');
tsickleCompilerHost.reconfigureForRun(programForJsEmit, tsickle.Pass.DECORATOR_DOWNLEVEL);
// A program can be re-used only once; save the programWithCodegen to be reused by
// metadataWriter
programForJsEmit = createProgram(tsickleCompilerHost);
check(tsickleCompilerHost.diagnostics);
if (diagnostics) console.timeEnd('NG downlevel');
}
if (ngOptions.annotateForClosureCompiler) {
if (diagnostics) console.time('NG JSDoc');
tsickleCompilerHost.reconfigureForRun(programForJsEmit, tsickle.Pass.CLOSURIZE);
programForJsEmit = createProgram(tsickleCompilerHost);
check(tsickleCompilerHost.diagnostics);
if (diagnostics) console.timeEnd('NG JSDoc');
}
// Emit *.js and *.js.map
tsc.emit(programForJsEmit);
// Emit *.d.ts and maybe *.metadata.json
// Not in the same emit pass with above, because tsickle erases
// decorators which we want to read or document.
// Do this emit second since TypeScript will create missing directories for us
// in the standard emit.
tsc.emit(programWithCodegen);
if (diagnostics) console.time('Emit');
const {diagnostics: emitDiags} =
tsickle.emitWithTsickle(programWithCodegen, tsickleHost, host, ngOptions);
if (diagnostics) console.timeEnd('Emit');
check(emitDiags);
if (diagnostics) {
(ts as any).performance.forEachMeasure(

View File

@ -67,8 +67,10 @@ export function formatDiagnostics(diags: ts.Diagnostic[]): string {
let res = ts.DiagnosticCategory[d.category];
if (d.file) {
res += ' at ' + d.file.fileName + ':';
const {line, character} = d.file.getLineAndCharacterOfPosition(d.start);
res += (line + 1) + ':' + (character + 1) + ':';
if (d.start !== undefined) {
const {line, character} = d.file.getLineAndCharacterOfPosition(d.start);
res += (line + 1) + ':' + (character + 1) + ':';
}
}
res += ' ' + ts.flattenDiagnosticMessageText(d.messageText, '\n');
return res;

View File

@ -75,7 +75,7 @@ describe('tsc-wrapped', () => {
// No helpers since decorators were lowered
expect(out).not.toContain('__decorate');
// Expand `export *` and fix index import
expect(out).toContain(`export { A, B } from './dep'`);
expect(out).toContain(`export { A, B } from "./dep"`);
// Annotated for Closure compiler
expect(out).toContain('* @param {?} x');
// Comments should stay multi-line
@ -112,7 +112,7 @@ describe('tsc-wrapped', () => {
.then(() => {
const out = readOut('js');
// Expand `export *` and fix index import
expect(out).toContain(`export { A, B } from './dep'`);
expect(out).toContain(`export { A, B } from "./dep"`);
// Annotated for Closure compiler
expect(out).toContain('* @param {?} x');
done();
@ -327,7 +327,7 @@ describe('tsc-wrapped', () => {
main(basePath, {basePath})
.then(() => {
const out = readOut('js.map');
expect(out).toContain('"sources":["other_test.ts","../test.ts"]');
expect(out).toContain('"sources":["other_test.ts"]');
done();
})
.catch(e => done.fail(e));
@ -361,7 +361,7 @@ describe('tsc-wrapped', () => {
main(basePath, {basePath})
.then(() => {
const out = readOut('js.map');
expect(out).toContain('"sources":["other_test.ts","../test.ts"]');
expect(out).toContain('"sources":["other_test.ts"]');
done();
})
.catch(e => done.fail(e));
@ -387,7 +387,7 @@ describe('tsc-wrapped', () => {
main(basePath, {basePath})
.then(() => {
const fileOutput = readOut('js');
expect(fileOutput).toContain(`export { A, B } from './dep'`);
expect(fileOutput).toContain(`export { A, B } from "./dep"`);
done();
})
.catch(e => done.fail(e));

View File

@ -97,7 +97,7 @@ describe('Symbols', () => {
switch (node.kind) {
case ts.SyntaxKind.VariableStatement:
case ts.SyntaxKind.VariableDeclarationList:
return ts.forEachChild(node, visit);
return !!ts.forEachChild(node, visit);
case ts.SyntaxKind.VariableDeclaration:
const variableDeclaration = <ts.VariableDeclaration>node;
const nameNode = <ts.Identifier>variableDeclaration.name;

View File

@ -34,6 +34,8 @@ export class Host implements ts.LanguageServiceHost {
if (content) return ts.ScriptSnapshot.fromString(content);
}
fileExists(fileName: string): boolean { return this.getFileContent(fileName) != null; }
getCurrentDirectory(): string { return '/'; }
getDefaultLibFileName(options: ts.CompilerOptions): string { return 'lib.d.ts'; }
@ -91,8 +93,10 @@ export class MockNode implements ts.Node {
getText(sourceFile?: ts.SourceFile): string { return ''; }
getFirstToken(sourceFile?: ts.SourceFile): ts.Node { return null as any as ts.Node; }
getLastToken(sourceFile?: ts.SourceFile): ts.Node { return null as any as ts.Node; }
forEachChild<T>(cbNode: (node: ts.Node) => T, cbNodeArray?: (nodes: ts.Node[]) => T): T {
return null as any as T;
forEachChild<T>(
cbNode: (node: ts.Node) => T | undefined,
cbNodeArray?: (nodes: ts.NodeArray<ts.Node>) => T | undefined): T|undefined {
return undefined;
}
}
@ -105,6 +109,7 @@ export class MockIdentifier extends MockNode implements ts.Identifier {
public _incrementExpressionBrand: any;
public _unaryExpressionBrand: any;
public _expressionBrand: any;
public _updateExpressionBrand: any;
// tslint:enable
constructor(
@ -149,9 +154,11 @@ export class MockSymbol implements ts.Symbol {
export function expectNoDiagnostics(diagnostics: ts.Diagnostic[]) {
for (const diagnostic of diagnostics) {
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
const {line, character} = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
// tslint:disable-next-line:no-console
console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
if (diagnostic.file && diagnostic.start) {
const {line, character} = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
// tslint:disable-next-line:no-console
console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
}
}
expect(diagnostics.length).toBe(0);
}
@ -164,14 +171,8 @@ export function expectValidSources(service: ts.LanguageService, program: ts.Prog
}
}
export function allChildren<T>(node: ts.Node, cb: (node: ts.Node) => T): T {
return ts.forEachChild(node, child => {
const result = cb(node);
if (result) {
return result;
}
return allChildren(child, cb);
});
export function allChildren<T>(node: ts.Node, cb: (node: ts.Node) => T | undefined): T|undefined {
return ts.forEachChild(node, child => cb(node) || allChildren(child, cb));
}
export function findClass(sourceFile: ts.SourceFile, name: string): ts.ClassDeclaration|undefined {