diff --git a/integration/hello_world__closure/package.json b/integration/hello_world__closure/package.json index f09cc3583c..e79b18dabd 100644 --- a/integration/hello_world__closure/package.json +++ b/integration/hello_world__closure/package.json @@ -13,7 +13,7 @@ "google-closure-compiler": "^20161201.0.0", "rxjs": "file:../../node_modules/rxjs", "source-map-explorer": "^1.3.3", - "typescript": "~2.0", + "typescript": "~2.1", "zone.js": "^0.7.6" }, "devDependencies": { diff --git a/integration/rxjs.tsconfig.json b/integration/rxjs.tsconfig.json index 775fb36b48..5c8124d186 100644 --- a/integration/rxjs.tsconfig.json +++ b/integration/rxjs.tsconfig.json @@ -5,12 +5,13 @@ "annotateForClosureCompiler": true }, - /** - * Remaining options are copied from - * https://github.com/ReactiveX/rxjs/blob/cba74135810a8e6bbe0b3c7732e8544b0869589e/tsconfig.json - * TODO(alexeagle): use "extends" instead when Angular is on TS 2.1 - */ "compilerOptions": { + "types": [], + /** + * Remaining options are copied from + * https://github.com/ReactiveX/rxjs/blob/cba74135810a8e6bbe0b3c7732e8544b0869589e/tsconfig.json + * TODO(alexeagle): use "extends" instead when Angular is on TS 2.1 + */ "removeComments": false, "preserveConstEnums": true, "sourceMap": true, diff --git a/integration/typings_test_ts20/include-all.ts b/integration/typings_test_ts21/include-all.ts similarity index 100% rename from integration/typings_test_ts20/include-all.ts rename to integration/typings_test_ts21/include-all.ts diff --git a/integration/typings_test_ts20/package.json b/integration/typings_test_ts21/package.json similarity index 97% rename from integration/typings_test_ts20/package.json rename to integration/typings_test_ts21/package.json index 52fa28cd24..cc9b76a83b 100644 --- a/integration/typings_test_ts20/package.json +++ b/integration/typings_test_ts21/package.json @@ -18,7 +18,7 @@ "@types/jasmine": "^2.5.41", "rxjs": "file:../../node_modules/rxjs", "source-map-explorer": "^1.3.3", - "typescript": "~2.0", + "typescript": "~2.1", "zone.js": "^0.7.6" }, "scripts": { diff --git a/integration/typings_test_ts20/tsconfig.json b/integration/typings_test_ts21/tsconfig.json similarity index 100% rename from integration/typings_test_ts20/tsconfig.json rename to integration/typings_test_ts21/tsconfig.json diff --git a/modules/@angular/benchpress/src/webdriver/chrome_driver_extension.ts b/modules/@angular/benchpress/src/webdriver/chrome_driver_extension.ts index aa7cd0c955..6109ed5b87 100644 --- a/modules/@angular/benchpress/src/webdriver/chrome_driver_extension.ts +++ b/modules/@angular/benchpress/src/webdriver/chrome_driver_extension.ts @@ -68,7 +68,7 @@ export class ChromeDriverExtension extends WebDriverExtension { .then((_) => this._driver.logs('performance')) .then((entries) => { const events: PerfLogEvent[] = []; - entries.forEach(entry => { + entries.forEach((entry: any) => { const message = JSON.parse(entry['message'])['message']; if (message['method'] === 'Tracing.dataCollected') { events.push(message['params']); diff --git a/modules/@angular/benchpress/src/webdriver/ios_driver_extension.ts b/modules/@angular/benchpress/src/webdriver/ios_driver_extension.ts index 5f55bc1111..effdd8b3b3 100644 --- a/modules/@angular/benchpress/src/webdriver/ios_driver_extension.ts +++ b/modules/@angular/benchpress/src/webdriver/ios_driver_extension.ts @@ -40,7 +40,7 @@ export class IOsDriverExtension extends WebDriverExtension { .then((_) => this._driver.logs('performance')) .then((entries) => { const records: any[] = []; - entries.forEach(entry => { + entries.forEach((entry: any) => { const message = JSON.parse(entry['message'])['message']; if (message['method'] === 'Timeline.eventRecorded') { records.push(message['params']['record']); diff --git a/modules/@angular/compiler-cli/test/main_spec.ts b/modules/@angular/compiler-cli/test/main_spec.ts index 370c9556ee..84f09a6379 100644 --- a/modules/@angular/compiler-cli/test/main_spec.ts +++ b/modules/@angular/compiler-cli/test/main_spec.ts @@ -154,7 +154,8 @@ describe('compiler-cli', () => { expect(mockConsole.error) .toHaveBeenCalledWith( 'Error at ' + path.join(basePath, 'test.ts') + - ':3:7: Cannot invoke an expression whose type lacks a call signature.'); + ':3:7: Cannot invoke an expression whose type lacks a call signature. ' + + 'Type \'String\' has no compatible call signatures.'); expect(mockConsole.error).not.toHaveBeenCalledWith('Compilation failed'); expect(exitCode).toEqual(1); done(); diff --git a/modules/@angular/compiler/src/expression_parser/lexer.ts b/modules/@angular/compiler/src/expression_parser/lexer.ts index 952aa37214..8f3cd60fc9 100644 --- a/modules/@angular/compiler/src/expression_parser/lexer.ts +++ b/modules/@angular/compiler/src/expression_parser/lexer.ts @@ -294,6 +294,8 @@ class _Scanner { buffer += input.substring(marker, this.index); this.advance(); let unescapedCode: number; + // Workaround for TS2.1-introduced type strictness + this.peek = this.peek; if (this.peek == chars.$u) { // 4 character hex code for unicode character. const hex: string = input.substring(this.index + 1, this.index + 5); diff --git a/modules/@angular/core/src/reflection/reflection_capabilities.ts b/modules/@angular/core/src/reflection/reflection_capabilities.ts index c3dba802c6..e93652d315 100644 --- a/modules/@angular/core/src/reflection/reflection_capabilities.ts +++ b/modules/@angular/core/src/reflection/reflection_capabilities.ts @@ -16,7 +16,7 @@ import {GetterFn, MethodFn, SetterFn} from './types'; * Attention: This regex has to hold even if the code is minified! */ export const DELEGATE_CTOR = - /^function\s+\S+\(\)\s*{\s*("use strict";)?\s*(return\s+)?\S+\.apply\(this,\s*arguments\)/; + /^function\s+\S+\(\)\s*{\s*("use strict";)?\s*(return\s+)?(\S+\s+!==\s+null\s+&&\s+)?\S+\.apply\(this,\s*arguments\)/; export class ReflectionCapabilities implements PlatformReflectionCapabilities { private _reflect: any; diff --git a/modules/@angular/examples/upgrade/static/ts/module.ts b/modules/@angular/examples/upgrade/static/ts/module.ts index be70348d7e..0f6a83f831 100644 --- a/modules/@angular/examples/upgrade/static/ts/module.ts +++ b/modules/@angular/examples/upgrade/static/ts/module.ts @@ -115,6 +115,7 @@ class Ng2AppModule { // #docregion Angular 1 Stuff // #docregion ng1-module // This Angular 1 module represents the AngularJS pieces of the application +declare var angular: ng.IAngularStatic; const ng1AppModule = angular.module('ng1AppModule', []); // #enddocregion diff --git a/modules/@angular/language-service/src/ts_plugin.ts b/modules/@angular/language-service/src/ts_plugin.ts index f24d5bd279..b4e6721f85 100644 --- a/modules/@angular/language-service/src/ts_plugin.ts +++ b/modules/@angular/language-service/src/ts_plugin.ts @@ -54,7 +54,12 @@ export function create(info: any /* ts.server.PluginCreateInfo */): ts.LanguageS const results = ls.getCompletionsAt(fileName, position); if (results && results.length) { if (base === undefined) { - base = {isMemberCompletion: false, isNewIdentifierLocation: false, entries: []}; + base = { + isGlobalCompletion: false, + isMemberCompletion: false, + isNewIdentifierLocation: false, + entries: [] + }; } for (const entry of results) { base.entries.push(completionToEntry(entry)); @@ -78,7 +83,8 @@ export function create(info: any /* ts.server.PluginCreateInfo */): ts.LanguageS documentation: [], kind: 'angular', kindModifiers: 'what does this do?', - textSpan: {start: ours.span.start, length: ours.span.end - ours.span.start} + textSpan: {start: ours.span.start, length: ours.span.end - ours.span.start}, + tags: [], }; } }); diff --git a/modules/@angular/router/src/apply_redirects.ts b/modules/@angular/router/src/apply_redirects.ts index 2b0aa4c452..779bebb3bd 100644 --- a/modules/@angular/router/src/apply_redirects.ts +++ b/modules/@angular/router/src/apply_redirects.ts @@ -20,7 +20,7 @@ import {EmptyError} from 'rxjs/util/EmptyError'; import {Route, Routes} from './config'; import {LoadedRouterConfig, RouterConfigLoader} from './router_config_loader'; -import {NavigationCancelingError, PRIMARY_OUTLET, Params, defaultUrlMatcher} from './shared'; +import {PRIMARY_OUTLET, Params, defaultUrlMatcher, navigationCancelingError} from './shared'; import {UrlSegment, UrlSegmentGroup, UrlSerializer, UrlTree} from './url_tree'; import {andObservables, forEach, merge, waitForMap, wrapIntoObservable} from './utils/collection'; @@ -50,7 +50,7 @@ function namedOutletsRedirect(redirectTo: string): Observable { function canLoadFails(route: Route): Observable { return new Observable( - (obs: Observer) => obs.error(new NavigationCancelingError( + (obs: Observer) => obs.error(navigationCancelingError( `Cannot load children because the guard of the route "path: '${route.path}'" returned false`))); } diff --git a/modules/@angular/router/src/router.ts b/modules/@angular/router/src/router.ts index 7c9cc789f6..a54175bd74 100644 --- a/modules/@angular/router/src/router.ts +++ b/modules/@angular/router/src/router.ts @@ -31,7 +31,7 @@ import {DetachedRouteHandle, DetachedRouteHandleInternal, RouteReuseStrategy} fr import {LoadedRouterConfig, RouterConfigLoader} from './router_config_loader'; import {RouterOutletMap} from './router_outlet_map'; import {ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot, advanceActivatedRoute, createEmptyState, equalParamsAndUrlSegments, inheritedParamsDataResolve} from './router_state'; -import {NavigationCancelingError, PRIMARY_OUTLET, Params} from './shared'; +import {PRIMARY_OUTLET, Params, isNavigationCancelingError} from './shared'; import {DefaultUrlHandlingStrategy, UrlHandlingStrategy} from './url_handling_strategy'; import {UrlSerializer, UrlTree, containsTree, createEmptyUrlTree} from './url_tree'; import {andObservables, forEach, merge, waitForMap, wrapIntoObservable} from './utils/collection'; @@ -802,7 +802,7 @@ export class Router { } }, (e: any) => { - if (e instanceof NavigationCancelingError) { + if (isNavigationCancelingError(e)) { this.resetUrlToCurrentUrlTree(); this.navigated = true; this.routerEvents.next( diff --git a/modules/@angular/router/src/shared.ts b/modules/@angular/router/src/shared.ts index bd2798710e..e98940baca 100644 --- a/modules/@angular/router/src/shared.ts +++ b/modules/@angular/router/src/shared.ts @@ -27,13 +27,16 @@ export type Params = { [key: string]: any }; -export class NavigationCancelingError extends Error { - public stack: any; - constructor(public message: string) { - super(message); - this.stack = (new Error(message)).stack; - } - toString(): string { return this.message; } +const NAVIGATION_CANCELING_ERROR = 'ngNavigationCancelingError'; + +export function navigationCancelingError(message: string) { + const error = Error('NavigationCancelingError: ' + message); + (error as any)[NAVIGATION_CANCELING_ERROR] = true; + return error; +} + +export function isNavigationCancelingError(error: Error) { + return (error as any)[NAVIGATION_CANCELING_ERROR]; } export function defaultUrlMatcher( diff --git a/modules/@angular/router/test/apply_redirects.spec.ts b/modules/@angular/router/test/apply_redirects.spec.ts index 87c60cef91..3e7afb8b38 100644 --- a/modules/@angular/router/test/apply_redirects.spec.ts +++ b/modules/@angular/router/test/apply_redirects.spec.ts @@ -214,7 +214,7 @@ describe('applyRedirects', () => { () => { throw 'Should not reach'; }, (e) => { expect(e.message).toEqual( - `Cannot load children because the guard of the route "path: 'a'" returned false`); + `NavigationCancelingError: Cannot load children because the guard of the route "path: 'a'" returned false`); }); }); diff --git a/tools/@angular/tsc-wrapped/src/main.ts b/tools/@angular/tsc-wrapped/src/main.ts index 325e6b30bf..54963a49e5 100644 --- a/tools/@angular/tsc-wrapped/src/main.ts +++ b/tools/@angular/tsc-wrapped/src/main.ts @@ -87,7 +87,7 @@ export function main( }; const tsickleHost: tsickle.TsickleHost = { - shouldSkipTsickleProcessing: (fileName) => false, + shouldSkipTsickleProcessing: (fileName) => /\.d\.ts$/.test(fileName), pathToModuleName: (context, importPath) => '', shouldIgnoreWarningsForPath: (filePath) => false, fileNameToModuleId: (fileName) => fileName, diff --git a/tools/@angular/tsc-wrapped/src/tsc.ts b/tools/@angular/tsc-wrapped/src/tsc.ts index 9e606aa783..96889c9439 100644 --- a/tools/@angular/tsc-wrapped/src/tsc.ts +++ b/tools/@angular/tsc-wrapped/src/tsc.ts @@ -30,17 +30,27 @@ export class UserError extends Error { private _nativeError: Error; constructor(message: string) { - // Errors don't use current this, instead they create a new instance. - // We have to do forward all of our api to the nativeInstance. - const nativeError = super(message) as any as Error; + super(message); + // Required for TS 2.1, see + // https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work + Object.setPrototypeOf(this, UserError.prototype); + + const nativeError = new Error(message) as any as Error; this._nativeError = nativeError; } get message() { return this._nativeError.message; } - set message(message) { this._nativeError.message = message; } - get name() { return 'UserError'; } + set message(message) { + if (this._nativeError) this._nativeError.message = message; + } + get name() { return this._nativeError.name; } + set name(name) { + if (this._nativeError) this._nativeError.name = name; + } get stack() { return (this._nativeError as any).stack; } - set stack(value) { (this._nativeError as any).stack = value; } + set stack(value) { + if (this._nativeError) (this._nativeError as any).stack = value; + } toString() { return this._nativeError.toString(); } } @@ -133,7 +143,8 @@ export class Tsc implements CompilerInterface { const host = { useCaseSensitiveFileNames: true, fileExists: existsSync, - readDirectory: this.readDirectory + readDirectory: this.readDirectory, + readFile: ts.sys.readFile }; this.parsed = ts.parseJsonConfigFileContent(config, host, basePath, existingOptions); diff --git a/tools/@angular/tsc-wrapped/test/tsc.spec.ts b/tools/@angular/tsc-wrapped/test/tsc.spec.ts index 8b694c46bd..68ca1e2d3d 100644 --- a/tools/@angular/tsc-wrapped/test/tsc.spec.ts +++ b/tools/@angular/tsc-wrapped/test/tsc.spec.ts @@ -7,7 +7,7 @@ */ import * as ts from 'typescript'; -import {Tsc, tsc as pureTsc} from '../src/tsc'; +import {Tsc} from '../src/tsc'; import {VinylFile} from '../src/vinyl_file'; describe('options parsing', () => { @@ -41,7 +41,7 @@ describe('options parsing', () => { }); it('should combine all options into ngOptions from vinyl like object', () => { - const {parsed, ngOptions} = pureTsc.readConfiguration(config as VinylFile, 'basePath'); + const {parsed, ngOptions} = tsc.readConfiguration(config as VinylFile, 'basePath'); expect(ngOptions).toEqual({ genDir: 'basePath', diff --git a/tools/@angular/tsc-wrapped/test/typescript.mocks.ts b/tools/@angular/tsc-wrapped/test/typescript.mocks.ts index 94df009dfb..663fc1afbe 100644 --- a/tools/@angular/tsc-wrapped/test/typescript.mocks.ts +++ b/tools/@angular/tsc-wrapped/test/typescript.mocks.ts @@ -89,8 +89,8 @@ export class MockIdentifier extends MockNode implements ts.Identifier { public _expressionBrand: any; constructor( - public name: string, kind: ts.SyntaxKind = ts.SyntaxKind.Identifier, flags: ts.NodeFlags = 0, - pos: number = 0, end: number = 0) { + public name: string, public kind: ts.SyntaxKind.Identifier = ts.SyntaxKind.Identifier, + flags: ts.NodeFlags = 0, pos: number = 0, end: number = 0) { super(kind, flags, pos, end); this.text = name; } @@ -100,7 +100,8 @@ export class MockVariableDeclaration extends MockNode implements ts.VariableDecl public _declarationBrand: any; constructor( - public name: ts.Identifier, kind: ts.SyntaxKind = ts.SyntaxKind.VariableDeclaration, + public name: ts.Identifier, + public kind: ts.SyntaxKind.VariableDeclaration = ts.SyntaxKind.VariableDeclaration, flags: ts.NodeFlags = 0, pos: number = 0, end: number = 0) { super(kind, flags, pos, end); } @@ -119,6 +120,7 @@ export class MockSymbol implements ts.Symbol { getName(): string { return this.name; } getDeclarations(): ts.Declaration[] { return [this.node]; } getDocumentationComment(): ts.SymbolDisplayPart[] { return []; } + getJsDocTags(): ts.JSDocTagInfo[]{return []}; static of (name: string): MockSymbol { return new MockSymbol(name); } } diff --git a/tools/tslint/requireInternalWithUnderscoreRule.ts b/tools/tslint/requireInternalWithUnderscoreRule.ts index e8afc10f3f..522edafae2 100644 --- a/tools/tslint/requireInternalWithUnderscoreRule.ts +++ b/tools/tslint/requireInternalWithUnderscoreRule.ts @@ -37,7 +37,7 @@ class TypedefWalker extends RuleWalker { private assertInternalAnnotationPresent(node: ts.Declaration) { if (node.name.getText().charAt(0) !== '_') return; - if (node.modifiers && node.modifiers.flags & ts.NodeFlags.Private) return; + if (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Private) return; const ranges = ts.getLeadingCommentRanges(this.getSourceFile().text, node.pos); if (ranges) {