Skip to content

Commit 2634a67

Browse files
committed
Merge branch 'master' into remove-jake
2 parents 2ff408f + 7890fd5 commit 2634a67

155 files changed

Lines changed: 1804 additions & 584 deletions

File tree

Some content is hidden

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

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,10 @@ These two files represent the DOM typings and are auto-generated. To make any mo
9191

9292
## Running the Tests
9393

94-
To run all tests, invoke the `runtests` target using jake:
94+
To run all tests, invoke the `runtests-parallel` target using jake:
9595

9696
```Shell
97-
jake runtests
97+
jake runtests-parallel
9898
```
9999

100100
This run will all tests; to run only a specific subset of tests, use:

scripts/mocha-parallel.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,6 @@ function runTests(taskConfigsFolder, run, options, cb) {
193193
counter--;
194194

195195
if (counter <= 0) {
196-
var failed = 0;
197196
var reporter = new Base(),
198197
stats = reporter.stats,
199198
failures = reporter.failures;
@@ -224,8 +223,8 @@ function runTests(taskConfigsFolder, run, options, cb) {
224223
reporter.epilogue();
225224
}
226225

227-
if (failed) {
228-
return cb(new Error("Test failures reported: " + failed));
226+
if (stats.failures) {
227+
return cb(new Error("Test failures reported: " + stats.failures));
229228
}
230229
else {
231230
return cb();

src/compiler/binder.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -610,10 +610,11 @@ namespace ts {
610610
case SyntaxKind.ExclamationEqualsToken:
611611
case SyntaxKind.EqualsEqualsEqualsToken:
612612
case SyntaxKind.ExclamationEqualsEqualsToken:
613-
if (isNarrowingExpression(expr.left) && (expr.right.kind === SyntaxKind.NullKeyword || expr.right.kind === SyntaxKind.Identifier)) {
613+
if ((isNarrowingExpression(expr.left) && (expr.right.kind === SyntaxKind.NullKeyword || expr.right.kind === SyntaxKind.Identifier)) ||
614+
(isNarrowingExpression(expr.right) && (expr.left.kind === SyntaxKind.NullKeyword || expr.left.kind === SyntaxKind.Identifier))) {
614615
return true;
615616
}
616-
if (expr.left.kind === SyntaxKind.TypeOfExpression && isNarrowingExpression((<TypeOfExpression>expr.left).expression) && expr.right.kind === SyntaxKind.StringLiteral) {
617+
if (isTypeOfNarrowingBinaryExpression(expr)) {
617618
return true;
618619
}
619620
return false;
@@ -625,6 +626,20 @@ namespace ts {
625626
return false;
626627
}
627628

629+
function isTypeOfNarrowingBinaryExpression(expr: BinaryExpression) {
630+
let typeOf: Expression;
631+
if (expr.left.kind === SyntaxKind.StringLiteral) {
632+
typeOf = expr.right;
633+
}
634+
else if (expr.right.kind === SyntaxKind.StringLiteral) {
635+
typeOf = expr.left;
636+
}
637+
else {
638+
typeOf = undefined;
639+
}
640+
return typeOf && typeOf.kind === SyntaxKind.TypeOfExpression && isNarrowingExpression((<TypeOfExpression>typeOf).expression);
641+
}
642+
628643
function createBranchLabel(): FlowLabel {
629644
return {
630645
flags: FlowFlags.BranchLabel,
@@ -1946,7 +1961,7 @@ namespace ts {
19461961
classPrototype.parent = leftSideOfAssignment;
19471962

19481963
const funcSymbol = container.locals[constructorFunction.text];
1949-
if (!funcSymbol || !(funcSymbol.flags & SymbolFlags.Function)) {
1964+
if (!funcSymbol || !(funcSymbol.flags & SymbolFlags.Function || isDeclarationOfFunctionExpression(funcSymbol))) {
19501965
return;
19511966
}
19521967

src/compiler/checker.ts

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7895,10 +7895,11 @@ namespace ts {
78957895
case SyntaxKind.ExclamationEqualsToken:
78967896
case SyntaxKind.EqualsEqualsEqualsToken:
78977897
case SyntaxKind.ExclamationEqualsEqualsToken:
7898-
if (isNullOrUndefinedLiteral(expr.right)) {
7898+
if (isNullOrUndefinedLiteral(expr.left) || isNullOrUndefinedLiteral(expr.right)) {
78997899
return narrowTypeByNullCheck(type, expr, assumeTrue);
79007900
}
7901-
if (expr.left.kind === SyntaxKind.TypeOfExpression && expr.right.kind === SyntaxKind.StringLiteral) {
7901+
if (expr.left.kind === SyntaxKind.TypeOfExpression && expr.right.kind === SyntaxKind.StringLiteral ||
7902+
expr.left.kind === SyntaxKind.StringLiteral && expr.right.kind === SyntaxKind.TypeOfExpression) {
79027903
return narrowTypeByTypeof(type, expr, assumeTrue);
79037904
}
79047905
break;
@@ -7911,18 +7912,20 @@ namespace ts {
79117912
}
79127913

79137914
function narrowTypeByNullCheck(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
7914-
// We have '==', '!=', '===', or '!==' operator with 'null' or 'undefined' on the right
7915+
// We have '==', '!=', '===', or '!==' operator with 'null' or 'undefined' on one side
79157916
const operator = expr.operatorToken.kind;
7917+
const nullLike = isNullOrUndefinedLiteral(expr.left) ? expr.left : expr.right;
7918+
const narrowed = isNullOrUndefinedLiteral(expr.left) ? expr.right : expr.left;
79167919
if (operator === SyntaxKind.ExclamationEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) {
79177920
assumeTrue = !assumeTrue;
79187921
}
7919-
if (!strictNullChecks || !isMatchingReference(reference, getReferenceFromExpression(expr.left))) {
7922+
if (!strictNullChecks || !isMatchingReference(reference, getReferenceFromExpression(narrowed))) {
79207923
return type;
79217924
}
79227925
const doubleEquals = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsToken;
79237926
const facts = doubleEquals ?
79247927
assumeTrue ? TypeFacts.EQUndefinedOrNull : TypeFacts.NEUndefinedOrNull :
7925-
expr.right.kind === SyntaxKind.NullKeyword ?
7928+
nullLike.kind === SyntaxKind.NullKeyword ?
79267929
assumeTrue ? TypeFacts.EQNull : TypeFacts.NENull :
79277930
assumeTrue ? TypeFacts.EQUndefined : TypeFacts.NEUndefined;
79287931
return getTypeWithFacts(type, facts);
@@ -7931,12 +7934,12 @@ namespace ts {
79317934
function narrowTypeByTypeof(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
79327935
// We have '==', '!=', '====', or !==' operator with 'typeof xxx' on the left
79337936
// and string literal on the right
7934-
const left = getReferenceFromExpression((<TypeOfExpression>expr.left).expression);
7935-
const right = <LiteralExpression>expr.right;
7936-
if (!isMatchingReference(reference, left)) {
7937+
const narrowed = getReferenceFromExpression((<TypeOfExpression>(expr.left.kind === SyntaxKind.TypeOfExpression ? expr.left : expr.right)).expression);
7938+
const literal = <LiteralExpression>(expr.right.kind === SyntaxKind.StringLiteral ? expr.right : expr.left);
7939+
if (!isMatchingReference(reference, narrowed)) {
79377940
// For a reference of the form 'x.y', a 'typeof x === ...' type guard resets the
79387941
// narrowed type of 'y' to its declared type.
7939-
if (containsMatchingReference(reference, left)) {
7942+
if (containsMatchingReference(reference, narrowed)) {
79407943
return declaredType;
79417944
}
79427945
return type;
@@ -7949,14 +7952,14 @@ namespace ts {
79497952
// We narrow a non-union type to an exact primitive type if the non-union type
79507953
// is a supertype of that primtive type. For example, type 'any' can be narrowed
79517954
// to one of the primitive types.
7952-
const targetType = getProperty(typeofTypesByName, right.text);
7955+
const targetType = getProperty(typeofTypesByName, literal.text);
79537956
if (targetType && isTypeSubtypeOf(targetType, type)) {
79547957
return targetType;
79557958
}
79567959
}
79577960
const facts = assumeTrue ?
7958-
getProperty(typeofEQFacts, right.text) || TypeFacts.TypeofEQHostObject :
7959-
getProperty(typeofNEFacts, right.text) || TypeFacts.TypeofNEHostObject;
7961+
getProperty(typeofEQFacts, literal.text) || TypeFacts.TypeofEQHostObject :
7962+
getProperty(typeofNEFacts, literal.text) || TypeFacts.TypeofNEHostObject;
79607963
return getTypeWithFacts(type, facts);
79617964
}
79627965

@@ -11492,8 +11495,12 @@ namespace ts {
1149211495
// When resolved signature is a call signature (and not a construct signature) the result type is any, unless
1149311496
// the declaring function had members created through 'x.prototype.y = expr' or 'this.y = expr' psuedodeclarations
1149411497
// in a JS file
11495-
const funcSymbol = checkExpression(node.expression).symbol;
11496-
if (funcSymbol && funcSymbol.members && (funcSymbol.flags & SymbolFlags.Function)) {
11498+
// Note:JS inferred classes might come from a variable declaration instead of a function declaration.
11499+
// In this case, using getResolvedSymbol directly is required to avoid losing the members from the declaration.
11500+
const funcSymbol = node.expression.kind === SyntaxKind.Identifier ?
11501+
getResolvedSymbol(node.expression as Identifier) :
11502+
checkExpression(node.expression).symbol;
11503+
if (funcSymbol && funcSymbol.members && (funcSymbol.flags & SymbolFlags.Function || isDeclarationOfFunctionExpression(funcSymbol))) {
1149711504
return getInferredClassType(funcSymbol);
1149811505
}
1149911506
else if (compilerOptions.noImplicitAny) {

src/compiler/commandLineParser.ts

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -337,8 +337,13 @@ namespace ts {
337337
}
338338
},
339339
{
340-
name: "typesRoot",
341-
type: "string"
340+
name: "typeRoots",
341+
type: "list",
342+
element: {
343+
name: "typeRoots",
344+
type: "string",
345+
isFilePath: true
346+
}
342347
},
343348
{
344349
name: "types",
@@ -488,13 +493,20 @@ namespace ts {
488493
}
489494

490495
/* @internal */
491-
export function parseListTypeOption(opt: CommandLineOptionOfListType, value: string, errors: Diagnostic[]): (string | number)[] {
492-
const values = trimString((value || "")).split(",");
496+
export function parseListTypeOption(opt: CommandLineOptionOfListType, value = "", errors: Diagnostic[]): (string | number)[] | undefined {
497+
value = trimString(value);
498+
if (startsWith(value, "-")) {
499+
return undefined;
500+
}
501+
if (value === "") {
502+
return [];
503+
}
504+
const values = value.split(",");
493505
switch (opt.element.type) {
494506
case "number":
495-
return ts.map(values, parseInt);
507+
return map(values, parseInt);
496508
case "string":
497-
return ts.map(values, v => v || "");
509+
return map(values, v => v || "");
498510
default:
499511
return filter(map(values, v => parseCustomTypeOption(<CommandLineOptionOfCustomType>opt.element, v, errors)), v => !!v);
500512
}
@@ -555,8 +567,11 @@ namespace ts {
555567
i++;
556568
break;
557569
case "list":
558-
options[opt.name] = parseListTypeOption(<CommandLineOptionOfListType>opt, args[i], errors);
559-
i++;
570+
const result = parseListTypeOption(<CommandLineOptionOfListType>opt, args[i], errors);
571+
options[opt.name] = result || [];
572+
if (result) {
573+
i++;
574+
}
560575
break;
561576
// If not a primitive, the possible types are specified in what is effectively a map of options.
562577
default:

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1931,6 +1931,10 @@
19311931
"category": "Error",
19321932
"code": 2687
19331933
},
1934+
"Cannot find type definition file for '{0}'.": {
1935+
"category": "Error",
1936+
"code": 2688
1937+
},
19341938
"Import declaration '{0}' is using private name '{1}'.": {
19351939
"category": "Error",
19361940
"code": 4000

src/compiler/emitter.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2150,9 +2150,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
21502150
}
21512151

21522152
// Return true if identifier resolves to an exported member of a namespace
2153-
function isNamespaceExportReference(node: Identifier) {
2153+
function isExportReference(node: Identifier) {
21542154
const container = resolver.getReferencedExportContainer(node);
2155-
return container && container.kind !== SyntaxKind.SourceFile;
2155+
return !!container;
21562156
}
21572157

21582158
// Return true if identifier resolves to an imported identifier
@@ -2185,10 +2185,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
21852185
// const foo_1 = require('./foo');
21862186
// exports.baz = { foo: foo_1.foo };
21872187
//
2188-
if (languageVersion < ScriptTarget.ES6 || (modulekind !== ModuleKind.ES6 && isImportedReference(node.name)) || isNamespaceExportReference(node.name) ) {
2188+
if (languageVersion < ScriptTarget.ES6 || (modulekind !== ModuleKind.ES6 && isImportedReference(node.name)) || isExportReference(node.name)) {
21892189
// Emit identifier as an identifier
21902190
write(": ");
2191-
emit(node.name);
2191+
emitExpressionIdentifier(node.name);
21922192
}
21932193

21942194
if (languageVersion >= ScriptTarget.ES6 && node.objectAssignmentInitializer) {
@@ -6133,10 +6133,10 @@ const _super = (function (geti, seti) {
61336133

61346134
if (parameters[i].dotDotDotToken) {
61356135
let parameterType = parameters[i].type;
6136-
if (parameterType.kind === SyntaxKind.ArrayType) {
6136+
if (parameterType && parameterType.kind === SyntaxKind.ArrayType) {
61376137
parameterType = (<ArrayTypeNode>parameterType).elementType;
61386138
}
6139-
else if (parameterType.kind === SyntaxKind.TypeReference && (<TypeReferenceNode>parameterType).typeArguments && (<TypeReferenceNode>parameterType).typeArguments.length === 1) {
6139+
else if (parameterType && parameterType.kind === SyntaxKind.TypeReference && (<TypeReferenceNode>parameterType).typeArguments && (<TypeReferenceNode>parameterType).typeArguments.length === 1) {
61406140
parameterType = (<TypeReferenceNode>parameterType).typeArguments[0];
61416141
}
61426142
else {
@@ -6156,9 +6156,15 @@ const _super = (function (geti, seti) {
61566156

61576157
/** Serializes the return type of function. Used by the __metadata decorator for a method. */
61586158
function emitSerializedReturnTypeOfNode(node: Node) {
6159-
if (node && isFunctionLike(node) && (<FunctionLikeDeclaration>node).type) {
6160-
emitSerializedTypeNode((<FunctionLikeDeclaration>node).type);
6161-
return;
6159+
if (node && isFunctionLike(node)) {
6160+
if ((<FunctionLikeDeclaration>node).type) {
6161+
emitSerializedTypeNode((<FunctionLikeDeclaration>node).type);
6162+
return;
6163+
}
6164+
else if (isAsyncFunctionLike(<FunctionLikeDeclaration>node)) {
6165+
write("Promise");
6166+
return;
6167+
}
61626168
}
61636169

61646170
write("void 0");

0 commit comments

Comments
 (0)