feat: typescript 3.6 support (#32946)

BREAKING CHANGE: typescript 3.4 and 3.5 are no longer supported, please update to typescript 3.6

Fixes #32380

PR Close #32946
This commit is contained in:
Igor Minar
2019-10-01 16:44:50 -07:00
committed by Matias Niemelä
parent 117ca7cf39
commit 86e1e6c082
89 changed files with 15550 additions and 5333 deletions

View File

@ -147,7 +147,8 @@ export class NgtscProgram implements api.Program {
}
if (generators.length > 0) {
this.host = new GeneratedShimsHostWrapper(host, generators);
// FIXME: Remove the any cast once google3 is fully on TS3.6.
this.host = (new GeneratedShimsHostWrapper(host, generators) as any);
}
this.tsProgram =

View File

@ -32,14 +32,13 @@ export interface ShimGenerator {
export class GeneratedShimsHostWrapper implements ts.CompilerHost {
constructor(private delegate: ts.CompilerHost, private shimGenerators: ShimGenerator[]) {
if (delegate.resolveModuleNames !== undefined) {
// FIXME: TypeScript 3.6 adds an "options" argument that the code below passes on, but which
// still makes the method incompatible with TS3.5. Remove the "as any" cast once fully on 3.6.
((this as ts.CompilerHost) as any).resolveModuleNames =
(moduleNames: string[], containingFile: string, reusedNames: (string[] | undefined),
redirectedReference: (ts.ResolvedProjectReference | undefined), options: any) =>
(delegate as any)
.resolveModuleNames !(
moduleNames, containingFile, reusedNames, redirectedReference, options);
this.resolveModuleNames =
(moduleNames: string[], containingFile: string, reusedNames: string[],
redirectedReference: ts.ResolvedProjectReference, options?: ts.CompilerOptions) =>
// FIXME: Additional parameters are required in TS3.6, but ignored in 3.5.
// Remove the any cast once google3 is fully on TS3.6.
(delegate.resolveModuleNames as any) !(
moduleNames, containingFile, reusedNames, redirectedReference, options);
}
if (delegate.resolveTypeReferenceDirectives) {
// Backward compatibility with TypeScript 2.9 and older since return
@ -59,6 +58,13 @@ export class GeneratedShimsHostWrapper implements ts.CompilerHost {
}
}
// FIXME: Additional options param is needed in TS3.6, but not alloowed in 3.5.
// Make the options param non-optional once google3 is fully on TS3.6.
resolveModuleNames?:
(moduleNames: string[], containingFile: string, reusedNames: string[],
redirectedReference: ts.ResolvedProjectReference,
options?: ts.CompilerOptions) => (ts.ResolvedModule | undefined)[];
resolveTypeReferenceDirectives?:
(names: string[], containingFile: string) => ts.ResolvedTypeReferenceDirective[];

View File

@ -14,8 +14,7 @@ describe('shim host', () => {
const delegate = {} as unknown as ts.CompilerHost;
const shimsHost = new GeneratedShimsHostWrapper(delegate, []);
// FIXME: re-enable once fully on TS3.6.
// expect(shimsHost.resolveModuleNames).not.toBeDefined();
expect(shimsHost.resolveModuleNames).not.toBeDefined();
expect(shimsHost.resolveTypeReferenceDirectives).not.toBeDefined();
expect(shimsHost.directoryExists).not.toBeDefined();
expect(shimsHost.getDirectories).not.toBeDefined();
@ -30,8 +29,7 @@ describe('shim host', () => {
} as unknown as ts.CompilerHost;
const shimsHost = new GeneratedShimsHostWrapper(delegate, []);
// FIXME: re-enable once fully on TS3.6.
// expect(shimsHost.resolveModuleNames).toBeDefined();
expect(shimsHost.resolveModuleNames).toBeDefined();
expect(shimsHost.resolveTypeReferenceDirectives).toBeDefined();
expect(shimsHost.directoryExists).toBeDefined();
expect(shimsHost.getDirectories).toBeDefined();

View File

@ -114,7 +114,7 @@ export function resolveModuleName(
compilerHost: ts.CompilerHost): ts.ResolvedModule|undefined {
if (compilerHost.resolveModuleNames) {
// FIXME: Additional parameters are required in TS3.6, but ignored in 3.5.
// Remove the any cast once fully on TS3.6.
// Remove the any cast once google3 is fully on TS3.6.
return (compilerHost as any)
.resolveModuleNames([moduleName], containingFile, undefined, undefined, compilerOptions)[0];
} else {

View File

@ -36,23 +36,30 @@ export function formatDiagnosticPosition(
}
export function flattenDiagnosticMessageChain(
chain: api.DiagnosticMessageChain, host: ts.FormatDiagnosticsHost = defaultFormatHost): string {
let result = chain.messageText;
let indent = 1;
let current = chain.next;
chain: api.DiagnosticMessageChain, host: ts.FormatDiagnosticsHost = defaultFormatHost,
indent = 0): string {
const newLine = host.getNewLine();
while (current) {
let result = '';
if (indent) {
result += newLine;
for (let i = 0; i < indent; i++) {
result += ' ';
}
result += current.messageText;
const position = current.position;
if (position) {
result += ` at ${formatDiagnosticPosition(position, host)}`;
}
result += chain.messageText;
const position = chain.position;
// add position if available, and we are not at the depest frame
if (position && indent !== 0) {
result += ` at ${formatDiagnosticPosition(position, host)}`;
}
indent++;
if (chain.next) {
for (const kid of chain.next) {
result += flattenDiagnosticMessageChain(kid, host, indent);
}
current = current.next;
indent++;
}
return result;
}

View File

@ -16,7 +16,7 @@ export const SOURCE = 'angular' as 'angular';
export interface DiagnosticMessageChain {
messageText: string;
position?: Position;
next?: DiagnosticMessageChain;
next?: DiagnosticMessageChain[];
}
export interface Diagnostic {

View File

@ -71,14 +71,14 @@ const defaultEmitCallback: TsEmitCallback =
* Minimum supported TypeScript version
* ∀ supported typescript version v, v >= MIN_TS_VERSION
*/
const MIN_TS_VERSION = '3.4.0';
const MIN_TS_VERSION = '3.6.4';
/**
* Supremum of supported TypeScript versions
* ∀ supported typescript version v, v < MAX_TS_VERSION
* MAX_TS_VERSION is not considered as a supported TypeScript version
*/
const MAX_TS_VERSION = '3.6.0';
const MAX_TS_VERSION = '3.7.0';
class AngularCompilerProgram implements Program {
private rootNames: string[];
@ -1109,7 +1109,7 @@ function diagnosticChainFromFormattedDiagnosticChain(chain: FormattedMessageChai
DiagnosticMessageChain {
return {
messageText: chain.message,
next: chain.next && diagnosticChainFromFormattedDiagnosticChain(chain.next),
next: chain.next && chain.next.map(diagnosticChainFromFormattedDiagnosticChain),
position: chain.position
};
}