Skip to content

Commit 8f4f6c5

Browse files
committed
Merge branch 'master' into ownJsonParsing
2 parents 8d771ca + 928da67 commit 8f4f6c5

File tree

210 files changed

+3881
-2726
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

210 files changed

+3881
-2726
lines changed

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ branches:
2121
- release-2.3
2222

2323
install:
24-
- npm uninstall typescript
25-
- npm uninstall tslint
24+
- npm uninstall typescript --no-save
25+
- npm uninstall tslint --no-save
2626
- npm install
2727

2828
cache:

jenkins.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
# Set up NVM
44
export NVM_DIR="/home/dotnet-bot/.nvm"
5-
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
5+
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
66

77
nvm install $1
88

9-
npm uninstall typescript
10-
npm uninstall tslint
9+
npm uninstall typescript --no-save
10+
npm uninstall tslint --no-save
1111
npm install
1212
npm update
1313
npm test

src/compiler/checker.ts

Lines changed: 62 additions & 70 deletions
Large diffs are not rendered by default.

src/compiler/core.ts

Lines changed: 77 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -752,18 +752,34 @@ namespace ts {
752752
return to;
753753
}
754754

755+
/**
756+
* Gets the actual offset into an array for a relative offset. Negative offsets indicate a
757+
* position offset from the end of the array.
758+
*/
759+
function toOffset(array: any[], offset: number) {
760+
return offset < 0 ? array.length + offset : offset;
761+
}
762+
755763
/**
756764
* Appends a range of value to an array, returning the array.
757765
*
758766
* @param to The array to which `value` is to be appended. If `to` is `undefined`, a new array
759767
* is created if `value` was appended.
760768
* @param from The values to append to the array. If `from` is `undefined`, nothing is
761769
* appended. If an element of `from` is `undefined`, that element is not appended.
770+
* @param start The offset in `from` at which to start copying values.
771+
* @param end The offset in `from` at which to stop copying values (non-inclusive).
762772
*/
763-
export function addRange<T>(to: T[] | undefined, from: T[] | undefined): T[] | undefined {
773+
export function addRange<T>(to: T[] | undefined, from: T[] | undefined, start?: number, end?: number): T[] | undefined {
764774
if (from === undefined) return to;
765-
for (const v of from) {
766-
to = append(to, v);
775+
if (to === undefined) return from.slice(start, end);
776+
start = start === undefined ? 0 : toOffset(from, start);
777+
end = end === undefined ? from.length : toOffset(from, end);
778+
for (let i = start; i < end && i < from.length; i++) {
779+
const v = from[i];
780+
if (v !== undefined) {
781+
to.push(from[i]);
782+
}
767783
}
768784
return to;
769785
}
@@ -788,28 +804,38 @@ namespace ts {
788804
return true;
789805
}
790806

807+
/**
808+
* Returns the element at a specific offset in an array if non-empty, `undefined` otherwise.
809+
* A negative offset indicates the element should be retrieved from the end of the array.
810+
*/
811+
export function elementAt<T>(array: T[] | undefined, offset: number): T | undefined {
812+
if (array) {
813+
offset = toOffset(array, offset);
814+
if (offset < array.length) {
815+
return array[offset];
816+
}
817+
}
818+
return undefined;
819+
}
820+
791821
/**
792822
* Returns the first element of an array if non-empty, `undefined` otherwise.
793823
*/
794-
export function firstOrUndefined<T>(array: T[]): T {
795-
return array && array.length > 0
796-
? array[0]
797-
: undefined;
824+
export function firstOrUndefined<T>(array: T[]): T | undefined {
825+
return elementAt(array, 0);
798826
}
799827

800828
/**
801829
* Returns the last element of an array if non-empty, `undefined` otherwise.
802830
*/
803-
export function lastOrUndefined<T>(array: T[]): T {
804-
return array && array.length > 0
805-
? array[array.length - 1]
806-
: undefined;
831+
export function lastOrUndefined<T>(array: T[]): T | undefined {
832+
return elementAt(array, -1);
807833
}
808834

809835
/**
810836
* Returns the only element of an array if it contains only one element, `undefined` otherwise.
811837
*/
812-
export function singleOrUndefined<T>(array: T[]): T {
838+
export function singleOrUndefined<T>(array: T[]): T | undefined {
813839
return array && array.length === 1
814840
? array[0]
815841
: undefined;
@@ -1137,6 +1163,15 @@ namespace ts {
11371163
return Array.isArray ? Array.isArray(value) : value instanceof Array;
11381164
}
11391165

1166+
export function tryCast<TOut extends TIn, TIn = any>(value: TIn | undefined, test: (value: TIn) => value is TOut): TOut | undefined {
1167+
return value !== undefined && test(value) ? value : undefined;
1168+
}
1169+
1170+
export function cast<TOut extends TIn, TIn = any>(value: TIn | undefined, test: (value: TIn) => value is TOut): TOut {
1171+
if (value !== undefined && test(value)) return value;
1172+
Debug.fail(`Invalid cast. The supplied value did not pass the test '${Debug.getFunctionName(test)}'.`);
1173+
}
1174+
11401175
/** Does nothing. */
11411176
export function noop(): void {}
11421177

@@ -2224,8 +2259,11 @@ namespace ts {
22242259
this.declarations = undefined;
22252260
}
22262261

2227-
function Type(this: Type, _checker: TypeChecker, flags: TypeFlags) {
2262+
function Type(this: Type, checker: TypeChecker, flags: TypeFlags) {
22282263
this.flags = flags;
2264+
if (Debug.isDebugging) {
2265+
this.checker = checker;
2266+
}
22292267
}
22302268

22312269
function Signature() {
@@ -2262,24 +2300,42 @@ namespace ts {
22622300

22632301
export namespace Debug {
22642302
export let currentAssertionLevel = AssertionLevel.None;
2303+
export let isDebugging = false;
22652304

22662305
export function shouldAssert(level: AssertionLevel): boolean {
22672306
return currentAssertionLevel >= level;
22682307
}
22692308

2270-
export function assert(expression: boolean, message?: string, verboseDebugInfo?: () => string): void {
2309+
export function assert(expression: boolean, message?: string, verboseDebugInfo?: () => string, stackCrawlMark?: Function): void {
22712310
if (!expression) {
2272-
let verboseDebugString = "";
22732311
if (verboseDebugInfo) {
2274-
verboseDebugString = "\r\nVerbose Debug Information: " + verboseDebugInfo();
2312+
message += "\r\nVerbose Debug Information: " + verboseDebugInfo();
22752313
}
2276-
debugger;
2277-
throw new Error("Debug Failure. False expression: " + (message || "") + verboseDebugString);
2314+
fail(message ? "False expression: " + message : "False expression.", stackCrawlMark || assert);
2315+
}
2316+
}
2317+
2318+
export function fail(message?: string, stackCrawlMark?: Function): void {
2319+
debugger;
2320+
const e = new Error(message ? `Debug Failure. ` : "Debug Failure.");
2321+
if ((<any>Error).captureStackTrace) {
2322+
(<any>Error).captureStackTrace(e, stackCrawlMark || fail);
22782323
}
2324+
throw e;
22792325
}
22802326

2281-
export function fail(message?: string): void {
2282-
Debug.assert(/*expression*/ false, message);
2327+
export function getFunctionName(func: Function) {
2328+
if (typeof func !== "function") {
2329+
return "";
2330+
}
2331+
else if (func.hasOwnProperty("name")) {
2332+
return (<any>func).name;
2333+
}
2334+
else {
2335+
const text = Function.prototype.toString.call(func);
2336+
const match = /^function\s+([\w\$]+)\s*\(/.exec(text);
2337+
return match ? match[1] : "";
2338+
}
22832339
}
22842340
}
22852341

@@ -2445,4 +2501,4 @@ namespace ts {
24452501
export function isCheckJsEnabledForFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) {
24462502
return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs;
24472503
}
2448-
}
2504+
}

src/compiler/factory.ts

Lines changed: 79 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2134,6 +2134,24 @@ namespace ts {
21342134

21352135
// Compound nodes
21362136

2137+
export function createImmediatelyInvokedFunctionExpression(statements: Statement[]): CallExpression;
2138+
export function createImmediatelyInvokedFunctionExpression(statements: Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression;
2139+
export function createImmediatelyInvokedFunctionExpression(statements: Statement[], param?: ParameterDeclaration, paramValue?: Expression) {
2140+
return createCall(
2141+
createFunctionExpression(
2142+
/*modifiers*/ undefined,
2143+
/*asteriskToken*/ undefined,
2144+
/*name*/ undefined,
2145+
/*typeParameters*/ undefined,
2146+
/*parameters*/ param ? [param] : [],
2147+
/*type*/ undefined,
2148+
createBlock(statements, /*multiLine*/ true)
2149+
),
2150+
/*typeArguments*/ undefined,
2151+
/*argumentsArray*/ paramValue ? [paramValue] : []
2152+
);
2153+
}
2154+
21372155
export function createComma(left: Expression, right: Expression) {
21382156
return <Expression>createBinary(left, SyntaxKind.CommaToken, right);
21392157
}
@@ -3208,6 +3226,26 @@ namespace ts {
32083226
return isBlock(node) ? node : setTextRange(createBlock([setTextRange(createReturn(node), node)], multiLine), node);
32093227
}
32103228

3229+
export function convertFunctionDeclarationToExpression(node: FunctionDeclaration) {
3230+
Debug.assert(!!node.body);
3231+
const updated = createFunctionExpression(
3232+
node.modifiers,
3233+
node.asteriskToken,
3234+
node.name,
3235+
node.typeParameters,
3236+
node.parameters,
3237+
node.type,
3238+
node.body
3239+
);
3240+
setOriginalNode(updated, node);
3241+
setTextRange(updated, node);
3242+
if (node.startsOnNewLine) {
3243+
updated.startsOnNewLine = true;
3244+
}
3245+
aggregateTransformFlags(updated);
3246+
return updated;
3247+
}
3248+
32113249
function isUseStrictPrologue(node: ExpressionStatement): boolean {
32123250
return (node.expression as StringLiteral).text === "use strict";
32133251
}
@@ -3606,7 +3644,7 @@ namespace ts {
36063644
if (kind === SyntaxKind.FunctionExpression || kind === SyntaxKind.ArrowFunction) {
36073645
const mutableCall = getMutableClone(emittedExpression);
36083646
mutableCall.expression = setTextRange(createParen(callee), callee);
3609-
return recreatePartiallyEmittedExpressions(expression, mutableCall);
3647+
return recreateOuterExpressions(expression, mutableCall, OuterExpressionKinds.PartiallyEmittedExpressions);
36103648
}
36113649
}
36123650
else {
@@ -3648,22 +3686,6 @@ namespace ts {
36483686
}
36493687
}
36503688

3651-
/**
3652-
* Clones a series of not-emitted expressions with a new inner expression.
3653-
*
3654-
* @param originalOuterExpression The original outer expression.
3655-
* @param newInnerExpression The new inner expression.
3656-
*/
3657-
function recreatePartiallyEmittedExpressions(originalOuterExpression: Expression, newInnerExpression: Expression) {
3658-
if (isPartiallyEmittedExpression(originalOuterExpression)) {
3659-
const clone = getMutableClone(originalOuterExpression);
3660-
clone.expression = recreatePartiallyEmittedExpressions(clone.expression, newInnerExpression);
3661-
return clone;
3662-
}
3663-
3664-
return newInnerExpression;
3665-
}
3666-
36673689
function getLeftmostExpression(node: Expression): Expression {
36683690
while (true) {
36693691
switch (node.kind) {
@@ -3710,6 +3732,22 @@ namespace ts {
37103732
All = Parentheses | Assertions | PartiallyEmittedExpressions
37113733
}
37123734

3735+
export type OuterExpression = ParenthesizedExpression | TypeAssertion | AsExpression | NonNullExpression | PartiallyEmittedExpression;
3736+
3737+
export function isOuterExpression(node: Node, kinds = OuterExpressionKinds.All): node is OuterExpression {
3738+
switch (node.kind) {
3739+
case SyntaxKind.ParenthesizedExpression:
3740+
return (kinds & OuterExpressionKinds.Parentheses) !== 0;
3741+
case SyntaxKind.TypeAssertionExpression:
3742+
case SyntaxKind.AsExpression:
3743+
case SyntaxKind.NonNullExpression:
3744+
return (kinds & OuterExpressionKinds.Assertions) !== 0;
3745+
case SyntaxKind.PartiallyEmittedExpression:
3746+
return (kinds & OuterExpressionKinds.PartiallyEmittedExpressions) !== 0;
3747+
}
3748+
return false;
3749+
}
3750+
37133751
export function skipOuterExpressions(node: Expression, kinds?: OuterExpressionKinds): Expression;
37143752
export function skipOuterExpressions(node: Node, kinds?: OuterExpressionKinds): Node;
37153753
export function skipOuterExpressions(node: Node, kinds = OuterExpressionKinds.All) {
@@ -3746,13 +3784,33 @@ namespace ts {
37463784
export function skipAssertions(node: Expression): Expression;
37473785
export function skipAssertions(node: Node): Node;
37483786
export function skipAssertions(node: Node): Node {
3749-
while (isAssertionExpression(node)) {
3750-
node = (<AssertionExpression>node).expression;
3787+
while (isAssertionExpression(node) || node.kind === SyntaxKind.NonNullExpression) {
3788+
node = (<AssertionExpression | NonNullExpression>node).expression;
37513789
}
37523790

37533791
return node;
37543792
}
37553793

3794+
function updateOuterExpression(outerExpression: OuterExpression, expression: Expression) {
3795+
switch (outerExpression.kind) {
3796+
case SyntaxKind.ParenthesizedExpression: return updateParen(outerExpression, expression);
3797+
case SyntaxKind.TypeAssertionExpression: return updateTypeAssertion(outerExpression, outerExpression.type, expression);
3798+
case SyntaxKind.AsExpression: return updateAsExpression(outerExpression, expression, outerExpression.type);
3799+
case SyntaxKind.NonNullExpression: return updateNonNullExpression(outerExpression, expression);
3800+
case SyntaxKind.PartiallyEmittedExpression: return updatePartiallyEmittedExpression(outerExpression, expression);
3801+
}
3802+
}
3803+
3804+
export function recreateOuterExpressions(outerExpression: Expression | undefined, innerExpression: Expression, kinds = OuterExpressionKinds.All): Expression {
3805+
if (outerExpression && isOuterExpression(outerExpression, kinds)) {
3806+
return updateOuterExpression(
3807+
outerExpression,
3808+
recreateOuterExpressions(outerExpression.expression, innerExpression)
3809+
);
3810+
}
3811+
return innerExpression;
3812+
}
3813+
37563814
export function startOnNewLine<T extends Node>(node: T): T {
37573815
node.startsOnNewLine = true;
37583816
return node;
@@ -3890,7 +3948,7 @@ namespace ts {
38903948
return bindingElement.right;
38913949
}
38923950

3893-
if (isSpreadExpression(bindingElement)) {
3951+
if (isSpreadElement(bindingElement)) {
38943952
// Recovery consistent with existing emit.
38953953
return getInitializerOfBindingOrAssignmentElement(<BindingOrAssignmentElement>bindingElement.expression);
38963954
}
@@ -3958,7 +4016,7 @@ namespace ts {
39584016
return getTargetOfBindingOrAssignmentElement(<BindingOrAssignmentElement>bindingElement.left);
39594017
}
39604018

3961-
if (isSpreadExpression(bindingElement)) {
4019+
if (isSpreadElement(bindingElement)) {
39624020
// `a` in `[...a] = ...`
39634021
return getTargetOfBindingOrAssignmentElement(<BindingOrAssignmentElement>bindingElement.expression);
39644022
}

0 commit comments

Comments
 (0)