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:

committed by
Matias Niemelä

parent
112e777b90
commit
ca5aebaa6b
@ -6,10 +6,10 @@
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@angular/compiler-cli": "0.0.0-PLACEHOLDER",
|
||||
"typescript": "~2.3"
|
||||
"typescript": "^2.4.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@bazel/typescript": "0.0.9"
|
||||
"@bazel/typescript": "0.1.x"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -155,15 +155,6 @@ export function compile(
|
||||
ngHost.toSummaryFileName = (fileName: string, referringSrcFileName: string) =>
|
||||
ngHost.fileNameToModuleName(fileName, referringSrcFileName);
|
||||
|
||||
const tsickleOpts = {
|
||||
googmodule: bazelOpts.googmodule,
|
||||
es5Mode: bazelOpts.es5Mode,
|
||||
prelude: bazelOpts.prelude,
|
||||
untyped: bazelOpts.untyped,
|
||||
typeBlackListPaths: new Set(bazelOpts.typeBlackListPaths),
|
||||
transformDecorators: bazelOpts.tsickle,
|
||||
transformTypesToClosure: bazelOpts.tsickle,
|
||||
};
|
||||
const emitCallback: ng.TsEmitCallback = ({
|
||||
program,
|
||||
targetSourceFile,
|
||||
@ -173,7 +164,7 @@ export function compile(
|
||||
customTransformers = {},
|
||||
}) =>
|
||||
tsickle.emitWithTsickle(
|
||||
program, bazelHost, tsickleOpts, bazelHost, compilerOpts, targetSourceFile, writeFile,
|
||||
program, bazelHost, bazelHost, compilerOpts, targetSourceFile, writeFile,
|
||||
cancellationToken, emitOnlyDtsFiles, {
|
||||
beforeTs: customTransformers.before,
|
||||
afterTs: customTransformers.after,
|
||||
|
@ -12,11 +12,11 @@
|
||||
"@angular/tsc-wrapped": "5.0.0-beta.6",
|
||||
"reflect-metadata": "^0.1.2",
|
||||
"minimist": "^1.2.0",
|
||||
"tsickle": "^0.23.6",
|
||||
"tsickle": "^0.24.0",
|
||||
"chokidar": "^1.4.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^2.0.2",
|
||||
"typescript": "^2.4.2",
|
||||
"@angular/compiler": "0.0.0-PLACEHOLDER"
|
||||
},
|
||||
"repository": {
|
||||
|
@ -137,23 +137,25 @@ export class TypeChecker {
|
||||
if (this._currentCancellationToken.isCancellationRequested()) return result;
|
||||
const sourceFile = program.getSourceFile(factoryName);
|
||||
for (const diagnostic of this.diagnosticProgram.getSemanticDiagnostics(sourceFile)) {
|
||||
const span = this.sourceSpanOf(diagnostic.file, diagnostic.start, diagnostic.length);
|
||||
if (span) {
|
||||
const fileName = span.start.file.url;
|
||||
const diagnosticsList = diagnosticsFor(fileName);
|
||||
diagnosticsList.push({
|
||||
messageText: diagnosticMessageToString(diagnostic.messageText),
|
||||
category: diagnostic.category, span,
|
||||
source: SOURCE,
|
||||
code: DEFAULT_ERROR_CODE
|
||||
});
|
||||
if (diagnostic.file && diagnostic.start) {
|
||||
const span = this.sourceSpanOf(diagnostic.file, diagnostic.start);
|
||||
if (span) {
|
||||
const fileName = span.start.file.url;
|
||||
const diagnosticsList = diagnosticsFor(fileName);
|
||||
diagnosticsList.push({
|
||||
messageText: diagnosticMessageToString(diagnostic.messageText),
|
||||
category: diagnostic.category, span,
|
||||
source: SOURCE,
|
||||
code: DEFAULT_ERROR_CODE
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private sourceSpanOf(source: ts.SourceFile, start: number, length: number): ParseSourceSpan|null {
|
||||
private sourceSpanOf(source: ts.SourceFile, start: number): ParseSourceSpan|null {
|
||||
// Find the corresponding TypeScript node
|
||||
const info = this.factories.get(source.fileName);
|
||||
if (info) {
|
||||
|
@ -193,7 +193,7 @@ class TypeScriptSymbolQuery implements SymbolQuery {
|
||||
const type = this.checker.getTypeAtLocation(parameter.type !);
|
||||
if (type.symbol !.name == 'TemplateRef' && isReferenceType(type)) {
|
||||
const typeReference = type as ts.TypeReference;
|
||||
if (typeReference.typeArguments.length === 1) {
|
||||
if (typeReference.typeArguments && typeReference.typeArguments.length === 1) {
|
||||
return typeReference.typeArguments[0].symbol;
|
||||
}
|
||||
}
|
||||
@ -261,7 +261,10 @@ class TypeWrapper implements Symbol {
|
||||
return this.context.checker.getNonNullableType(this.tsType) != this.tsType;
|
||||
}
|
||||
|
||||
get definition(): Definition { return definitionFromTsSymbol(this.tsType.getSymbol()); }
|
||||
get definition(): Definition|undefined {
|
||||
const symbol = this.tsType.getSymbol();
|
||||
return symbol ? definitionFromTsSymbol(symbol) : undefined;
|
||||
}
|
||||
|
||||
members(): SymbolTable {
|
||||
return new SymbolTableWrapper(this.tsType.getProperties(), this.context);
|
||||
@ -528,7 +531,10 @@ class PipeSymbol implements Symbol {
|
||||
|
||||
get public(): boolean { return true; }
|
||||
|
||||
get definition(): Definition { return definitionFromTsSymbol(this.tsType.getSymbol()); }
|
||||
get definition(): Definition|undefined {
|
||||
const symbol = this.tsType.getSymbol();
|
||||
return symbol ? definitionFromTsSymbol(symbol) : undefined;
|
||||
}
|
||||
|
||||
members(): SymbolTable { return EmptyTable.instance; }
|
||||
|
||||
|
@ -55,7 +55,11 @@ export function mainSync(
|
||||
}
|
||||
|
||||
function createEmitCallback(options: api.CompilerOptions): api.TsEmitCallback {
|
||||
const tsickleOptions: tsickle.TransformerOptions = {
|
||||
const tsickleHost: tsickle.TsickleHost = {
|
||||
shouldSkipTsickleProcessing: (fileName) => /\.d\.ts$/.test(fileName),
|
||||
pathToModuleName: (context, importPath) => '',
|
||||
shouldIgnoreWarningsForPath: (filePath) => false,
|
||||
fileNameToModuleId: (fileName) => fileName,
|
||||
googmodule: false,
|
||||
untyped: true,
|
||||
convertIndexImportShorthand: true,
|
||||
@ -63,13 +67,6 @@ function createEmitCallback(options: api.CompilerOptions): api.TsEmitCallback {
|
||||
transformTypesToClosure: options.annotateForClosureCompiler,
|
||||
};
|
||||
|
||||
const tsickleHost: tsickle.TransformerHost = {
|
||||
shouldSkipTsickleProcessing: (fileName) => /\.d\.ts$/.test(fileName),
|
||||
pathToModuleName: (context, importPath) => '',
|
||||
shouldIgnoreWarningsForPath: (filePath) => false,
|
||||
fileNameToModuleId: (fileName) => fileName,
|
||||
};
|
||||
|
||||
return ({
|
||||
program,
|
||||
targetSourceFile,
|
||||
@ -81,7 +78,7 @@ function createEmitCallback(options: api.CompilerOptions): api.TsEmitCallback {
|
||||
options
|
||||
}) =>
|
||||
tsickle.emitWithTsickle(
|
||||
program, tsickleHost, tsickleOptions, host, options, targetSourceFile, writeFile,
|
||||
program, tsickleHost, host, options, targetSourceFile, writeFile,
|
||||
cancellationToken, emitOnlyDtsFiles, {
|
||||
beforeTs: customTransformers.before,
|
||||
afterTs: customTransformers.after,
|
||||
|
@ -142,8 +142,8 @@ export function performCompilation({rootNames, options, host, oldProgram, emitCa
|
||||
}): PerformCompilationResult {
|
||||
const [major, minor] = ts.version.split('.');
|
||||
|
||||
if (Number(major) < 2 || (Number(major) === 2 && Number(minor) < 3)) {
|
||||
throw new Error('Must use TypeScript > 2.3 to have transformer support');
|
||||
if (Number(major) < 2 || (Number(major) === 2 && Number(minor) < 4)) {
|
||||
throw new Error('The Angular Compiler requires TypeScript >= 2.4.');
|
||||
}
|
||||
|
||||
let program: api.Program|undefined;
|
||||
|
@ -190,7 +190,7 @@ class _NodeEmitterVisitor implements StatementVisitor, ExpressionVisitor {
|
||||
// TODO {chuckj}: Determine what should be done for a method with a null name.
|
||||
const methods = stmt.methods.filter(method => method.name)
|
||||
.map(
|
||||
method => ts.createMethodDeclaration(
|
||||
method => ts.createMethod(
|
||||
/* decorators */ undefined, /* modifiers */ undefined,
|
||||
/* astriskToken */ undefined, method.name !/* guarded by filter */,
|
||||
/* questionToken */ undefined, /* typeParameters */ undefined,
|
||||
|
@ -70,8 +70,10 @@ describe('ng type checker', () => {
|
||||
it('should accept a safe property access of a nullable person',
|
||||
() => { a('{{maybePerson?.name}}'); });
|
||||
it('should accept a function call', () => { a('{{getName()}}'); });
|
||||
it('should reject an invalid method',
|
||||
() => { r('{{getFame()}}', `Property 'getFame' does not exist on type 'AppComponent'.`); });
|
||||
it('should reject an invalid method', () => {
|
||||
r('{{getFame()}}',
|
||||
`Property 'getFame' does not exist on type 'AppComponent'. Did you mean 'getName'?`);
|
||||
});
|
||||
it('should accept a field access of a method result', () => { a('{{getPerson().name}}'); });
|
||||
it('should reject an invalid field reference of a method result',
|
||||
() => { r('{{getPerson().fame}}', `Property 'fame' does not exist on type 'Person'.`); });
|
||||
|
@ -63,8 +63,9 @@ export interface IterableChanges<V> {
|
||||
* of the item, after applying the operations up to this point.
|
||||
*/
|
||||
forEachOperation(
|
||||
fn: (record: IterableChangeRecord<V>, previousIndex: number, currentIndex: number) => void):
|
||||
void;
|
||||
fn:
|
||||
(record: IterableChangeRecord<V>, previousIndex: number|null,
|
||||
currentIndex: number|null) => void): void;
|
||||
|
||||
/**
|
||||
* Iterate over changes in the order of original `Iterable` showing where the original items
|
||||
|
@ -647,9 +647,9 @@ function commonTests() {
|
||||
it('should call onUnstable and onMicrotaskEmpty before and after each turn, respectively',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
let aResolve: (result: string | null) => void;
|
||||
let aPromise: Promise<string>;
|
||||
let aPromise: Promise<string|null>;
|
||||
let bResolve: (result: string | null) => void;
|
||||
let bPromise: Promise<string>;
|
||||
let bPromise: Promise<string|null>;
|
||||
|
||||
runNgZoneNoLog(() => {
|
||||
macroTask(() => {
|
||||
|
@ -140,7 +140,7 @@ ng1AppModule.factory(
|
||||
|
||||
// #docregion downgrade-ng2-heroes-service
|
||||
// Register an AngularJS service, whose value is the "downgraded" Angular injectable.
|
||||
ng1AppModule.factory('heroesService', downgradeInjectable(HeroesService));
|
||||
ng1AppModule.factory('heroesService', downgradeInjectable(HeroesService) as any);
|
||||
// #enddocregion
|
||||
|
||||
// #docregion ng2-heroes-wrapper
|
||||
|
@ -67,7 +67,10 @@ function angularOnlyFilter(ls: ts.LanguageService): ts.LanguageService {
|
||||
getCodeFixesAtPosition: (fileName, start, end, errorCodes) => <ts.CodeAction[]>[],
|
||||
getEmitOutput: fileName => <ts.EmitOutput><any>undefined,
|
||||
getProgram: () => ls.getProgram(),
|
||||
dispose: () => ls.dispose()
|
||||
dispose: () => ls.dispose(),
|
||||
getApplicableRefactors: (fileName, positionOrRaneg) => <ts.ApplicableRefactorInfo[]>[],
|
||||
getEditsForRefactor: (fileName, formatOptions, positionOrRange, refactorName, actionName) =>
|
||||
undefined,
|
||||
};
|
||||
}
|
||||
|
||||
@ -162,7 +165,10 @@ export function create(info: any /* ts.server.PluginCreateInfo */): ts.LanguageS
|
||||
getCodeFixesAtPosition: tryFilenameFourCall(ls.getCodeFixesAtPosition),
|
||||
getEmitOutput: tryFilenameCall(ls.getEmitOutput),
|
||||
getProgram: () => ls.getProgram(),
|
||||
dispose: () => ls.dispose()
|
||||
dispose: () => ls.dispose(),
|
||||
getApplicableRefactors: (fileName, positionOrRaneg) => <ts.ApplicableRefactorInfo[]>[],
|
||||
getEditsForRefactor: (fileName, formatOptions, positionOrRange, refactorName, actionName) =>
|
||||
undefined,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -147,6 +147,8 @@ export class MockTypescriptHost implements ts.LanguageServiceHost {
|
||||
return fs.existsSync(effectiveName);
|
||||
}
|
||||
|
||||
fileExists(fileName: string): boolean { return this.getRawFileContent(fileName) != null; }
|
||||
|
||||
getMarkerLocations(fileName: string): {[name: string]: number}|undefined {
|
||||
let content = this.getRawFileContent(fileName);
|
||||
if (content) {
|
||||
|
@ -259,7 +259,7 @@ function expectEntries(locationMarker: string, info: ts.CompletionInfo, ...names
|
||||
function expectNoDiagnostics(diagnostics: ts.Diagnostic[]) {
|
||||
for (const diagnostic of diagnostics) {
|
||||
let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
|
||||
if (diagnostic.start) {
|
||||
if (diagnostic.file && diagnostic.start) {
|
||||
let {line, character} = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
||||
console.error(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
|
||||
} else {
|
||||
|
@ -12,6 +12,7 @@
|
||||
"@angular/common": "file:../../../dist/packages-dist/common",
|
||||
"@angular/compiler": "file:../../../dist/packages-dist/compiler",
|
||||
"@angular/compiler-cli": "file:../../../dist/packages-dist/compiler-cli",
|
||||
"@angular/tsc-wrapped": "file:../../../dist/packages-dist/tsc-wrapped",
|
||||
"@angular/core": "file:../../../dist/packages-dist/core",
|
||||
"@angular/http": "file:../../../dist/packages-dist/http",
|
||||
"@angular/platform-browser": "file:../../../dist/packages-dist/platform-browser",
|
||||
@ -19,8 +20,8 @@
|
||||
"@angular/platform-server": "file:../../../dist/packages-dist/platform-server",
|
||||
"express": "^4.14.1",
|
||||
"rxjs": "file:../../../node_modules/rxjs",
|
||||
"typescript": "2.3.x",
|
||||
"zone.js": "^0.8.10"
|
||||
"typescript": "file:../../../node_modules/typescript",
|
||||
"zone.js": "file:../../../node_modules/zone.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jasmine": "2.5.41",
|
||||
@ -33,7 +34,7 @@
|
||||
"webpack": "^2.2.1"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "webdriver-manager update",
|
||||
"postinstall": "webdriver-manager update --gecko false",
|
||||
"build": "./build.sh",
|
||||
"test": "npm run build && concurrently \"npm run serve\" \"npm run protractor\" --kill-others --success first",
|
||||
"serve": "node built/server-bundle.js",
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -18,6 +18,9 @@
|
||||
// don't auto-discover @types/node, it results in a ///<reference in the .d.ts output
|
||||
"types": [],
|
||||
"experimentalDecorators": true,
|
||||
// This is needed due to https://github.com/Microsoft/TypeScript/issues/17516.
|
||||
// As tsickle will lower decorators before TS, this is not a problem for our build.
|
||||
"emitDecoratorMetadata": true,
|
||||
"sourceMap": true,
|
||||
"inlineSources": true
|
||||
}
|
||||
|
@ -550,9 +550,10 @@ export class UpgradeAdapter {
|
||||
(ng1Injector: angular.IInjectorService, rootScope: angular.IRootScopeService) => {
|
||||
UpgradeNg1ComponentAdapterBuilder.resolve(this.ng1ComponentsToBeUpgraded, ng1Injector)
|
||||
.then(() => {
|
||||
// At this point we have ng1 injector and we have prepared
|
||||
// ng1 components to be upgraded, we now can bootstrap ng2.
|
||||
@NgModule({
|
||||
// Note: There is a bug in TS 2.4 that prevents us from
|
||||
// inlining this into @NgModule
|
||||
// TODO(tbosch): find or file a bug against TypeScript for this.
|
||||
const ngModule = {
|
||||
providers: [
|
||||
{provide: $INJECTOR, useFactory: () => ng1Injector},
|
||||
{provide: $COMPILE, useFactory: () => ng1Injector.get($COMPILE)},
|
||||
@ -560,7 +561,10 @@ export class UpgradeAdapter {
|
||||
],
|
||||
imports: [this.ng2AppModule],
|
||||
entryComponents: this.downgradedComponents
|
||||
})
|
||||
};
|
||||
// At this point we have ng1 injector and we have prepared
|
||||
// ng1 components to be upgraded, we now can bootstrap ng2.
|
||||
@NgModule(ngModule)
|
||||
class DynamicNgUpgradeModule {
|
||||
constructor() {}
|
||||
ngDoBootstrap() {}
|
||||
|
@ -38,7 +38,12 @@ export class UpgradeNg1ComponentAdapterBuilder {
|
||||
name.replace(CAMEL_CASE, (all: string, next: string) => '-' + next.toLowerCase());
|
||||
const self = this;
|
||||
|
||||
@Directive({selector: selector, inputs: this.inputsRename, outputs: this.outputsRename})
|
||||
// Note: There is a bug in TS 2.4 that prevents us from
|
||||
// inlining this into @Directive
|
||||
// TODO(tbosch): find or file a bug against TypeScript for this.
|
||||
const directive = {selector: selector, inputs: this.inputsRename, outputs: this.outputsRename};
|
||||
|
||||
@Directive(directive)
|
||||
class MyClass {
|
||||
directive: angular.IDirective;
|
||||
constructor(
|
||||
|
Reference in New Issue
Block a user