Skip to content

Commit 3c4fd9f

Browse files
committed
Merge branch 'master' of https://github.com/Microsoft/TypeScript into feature/eslint
2 parents b4902f0 + 375487e commit 3c4fd9f

File tree

86 files changed

+1547
-488
lines changed

Some content is hidden

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

86 files changed

+1547
-488
lines changed

src/compiler/checker.ts

Lines changed: 29 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9526,44 +9526,13 @@ namespace ts {
95269526
return false;
95279527
}
95289528

9529-
// Return true if the given intersection type contains
9530-
// more than one unit type or,
9531-
// an object type and a nullable type (null or undefined), or
9532-
// a string-like type and a type known to be non-string-like, or
9533-
// a number-like type and a type known to be non-number-like, or
9534-
// a symbol-like type and a type known to be non-symbol-like, or
9535-
// a void-like type and a type known to be non-void-like, or
9536-
// a non-primitive type and a type known to be primitive.
9537-
function isEmptyIntersectionType(type: IntersectionType) {
9538-
let combined: TypeFlags = 0;
9539-
for (const t of type.types) {
9540-
if (t.flags & TypeFlags.Unit && combined & TypeFlags.Unit) {
9541-
return true;
9542-
}
9543-
combined |= t.flags;
9544-
if (combined & TypeFlags.Nullable && combined & (TypeFlags.Object | TypeFlags.NonPrimitive) ||
9545-
combined & TypeFlags.NonPrimitive && combined & (TypeFlags.DisjointDomains & ~TypeFlags.NonPrimitive) ||
9546-
combined & TypeFlags.StringLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.StringLike) ||
9547-
combined & TypeFlags.NumberLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.NumberLike) ||
9548-
combined & TypeFlags.BigIntLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.BigIntLike) ||
9549-
combined & TypeFlags.ESSymbolLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.ESSymbolLike) ||
9550-
combined & TypeFlags.VoidLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.VoidLike)) {
9551-
return true;
9552-
}
9553-
}
9554-
return false;
9555-
}
9556-
95579529
function addTypeToUnion(typeSet: Type[], includes: TypeFlags, type: Type) {
95589530
const flags = type.flags;
95599531
if (flags & TypeFlags.Union) {
95609532
return addTypesToUnion(typeSet, includes, (<UnionType>type).types);
95619533
}
9562-
// We ignore 'never' types in unions. Likewise, we ignore intersections of unit types as they are
9563-
// another form of 'never' (in that they have an empty value domain). We could in theory turn
9564-
// intersections of unit types into 'never' upon construction, but deferring the reduction makes it
9565-
// easier to reason about their origin.
9566-
if (!(flags & TypeFlags.Never || flags & TypeFlags.Intersection && isEmptyIntersectionType(<IntersectionType>type))) {
9534+
// We ignore 'never' types in unions
9535+
if (!(flags & TypeFlags.Never)) {
95679536
includes |= flags & TypeFlags.IncludesMask;
95689537
if (flags & TypeFlags.StructuredOrInstantiable) includes |= TypeFlags.IncludesStructuredOrInstantiable;
95699538
if (type === wildcardType) includes |= TypeFlags.IncludesWildcard;
@@ -9787,13 +9756,18 @@ namespace ts {
97879756
}
97889757
}
97899758
else {
9790-
includes |= flags & TypeFlags.IncludesMask;
97919759
if (flags & TypeFlags.AnyOrUnknown) {
97929760
if (type === wildcardType) includes |= TypeFlags.IncludesWildcard;
97939761
}
97949762
else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !contains(typeSet, type)) {
9763+
if (type.flags & TypeFlags.Unit && includes & TypeFlags.Unit) {
9764+
// We have seen two distinct unit types which means we should reduce to an
9765+
// empty intersection. Adding TypeFlags.NonPrimitive causes that to happen.
9766+
includes |= TypeFlags.NonPrimitive;
9767+
}
97959768
typeSet.push(type);
97969769
}
9770+
includes |= flags & TypeFlags.IncludesMask;
97979771
}
97989772
return includes;
97999773
}
@@ -9909,7 +9883,23 @@ namespace ts {
99099883
function getIntersectionType(types: readonly Type[], aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type {
99109884
const typeSet: Type[] = [];
99119885
const includes = addTypesToIntersection(typeSet, 0, types);
9912-
if (includes & TypeFlags.Never) {
9886+
// An intersection type is considered empty if it contains
9887+
// the type never, or
9888+
// more than one unit type or,
9889+
// an object type and a nullable type (null or undefined), or
9890+
// a string-like type and a type known to be non-string-like, or
9891+
// a number-like type and a type known to be non-number-like, or
9892+
// a symbol-like type and a type known to be non-symbol-like, or
9893+
// a void-like type and a type known to be non-void-like, or
9894+
// a non-primitive type and a type known to be primitive.
9895+
if (includes & TypeFlags.Never ||
9896+
strictNullChecks && includes & TypeFlags.Nullable && includes & (TypeFlags.Object | TypeFlags.NonPrimitive | TypeFlags.IncludesEmptyObject) ||
9897+
includes & TypeFlags.NonPrimitive && includes & (TypeFlags.DisjointDomains & ~TypeFlags.NonPrimitive) ||
9898+
includes & TypeFlags.StringLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.StringLike) ||
9899+
includes & TypeFlags.NumberLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.NumberLike) ||
9900+
includes & TypeFlags.BigIntLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.BigIntLike) ||
9901+
includes & TypeFlags.ESSymbolLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.ESSymbolLike) ||
9902+
includes & TypeFlags.VoidLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.VoidLike)) {
99139903
return neverType;
99149904
}
99159905
if (includes & TypeFlags.Any) {
@@ -14633,7 +14623,7 @@ namespace ts {
1463314623
}
1463414624

1463514625
function createSymbolWithType(source: Symbol, type: Type | undefined) {
14636-
const symbol = createSymbol(source.flags, source.escapedName);
14626+
const symbol = createSymbol(source.flags, source.escapedName, getCheckFlags(source) & CheckFlags.Readonly);
1463714627
symbol.declarations = source.declarations;
1463814628
symbol.parent = source.parent;
1463914629
symbol.type = type;
@@ -19093,8 +19083,8 @@ namespace ts {
1909319083
}
1909419084

1909519085
function checkSpreadExpression(node: SpreadElement, checkMode?: CheckMode): Type {
19096-
if (languageVersion < ScriptTarget.ES2015 && compilerOptions.downlevelIteration) {
19097-
checkExternalEmitHelpers(node, ExternalEmitHelpers.SpreadIncludes);
19086+
if (languageVersion < ScriptTarget.ES2015) {
19087+
checkExternalEmitHelpers(node, compilerOptions.downlevelIteration ? ExternalEmitHelpers.SpreadIncludes : ExternalEmitHelpers.SpreadArrays);
1909819088
}
1909919089

1910019090
const arrayOrIterableType = checkExpression(node.expression, checkMode);
@@ -31127,6 +31117,7 @@ namespace ts {
3112731117
case ExternalEmitHelpers.Values: return "__values";
3112831118
case ExternalEmitHelpers.Read: return "__read";
3112931119
case ExternalEmitHelpers.Spread: return "__spread";
31120+
case ExternalEmitHelpers.SpreadArrays: return "__spreadArrays";
3113031121
case ExternalEmitHelpers.Await: return "__await";
3113131122
case ExternalEmitHelpers.AsyncGenerator: return "__asyncGenerator";
3113231123
case ExternalEmitHelpers.AsyncDelegator: return "__asyncDelegator";

src/compiler/factory.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2658,6 +2658,7 @@ namespace ts {
26582658
valuesHelper,
26592659
readHelper,
26602660
spreadHelper,
2661+
spreadArraysHelper,
26612662
restHelper,
26622663
decorateHelper,
26632664
metadataHelper,
@@ -3693,6 +3694,31 @@ namespace ts { // eslint-disable-line no-redeclare
36933694
);
36943695
}
36953696

3697+
export const spreadArraysHelper: UnscopedEmitHelper = {
3698+
name: "typescript:spreadArrays",
3699+
scoped: false,
3700+
text: `
3701+
var __spreadArrays = (this && this.__spreadArrays) || function () {
3702+
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
3703+
for (var r = Array(s), k = 0, i = 0; i < il; i++)
3704+
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
3705+
r[k] = a[j];
3706+
return r;
3707+
};`
3708+
};
3709+
3710+
export function createSpreadArraysHelper(context: TransformationContext, argumentList: ReadonlyArray<Expression>, location?: TextRange) {
3711+
context.requestEmitHelper(spreadArraysHelper);
3712+
return setTextRange(
3713+
createCall(
3714+
getHelperName("__spreadArrays"),
3715+
/*typeArguments*/ undefined,
3716+
argumentList
3717+
),
3718+
location
3719+
);
3720+
}
3721+
36963722
// Utilities
36973723

36983724
export function createForOfBindingStatement(node: ForInitializer, boundValue: Expression): Statement {

src/compiler/transformers/es2015.ts

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3819,8 +3819,11 @@ namespace ts {
38193819
// [source]
38203820
// [a, ...b, c]
38213821
//
3822+
// [output (downlevelIteration)]
3823+
// __spread([a], b, [c])
3824+
//
38223825
// [output]
3823-
// [a].concat(b, [c])
3826+
// __spreadArrays([a], b, [c])
38243827

38253828
// Map spans of spread expressions into their expressions and spans of other
38263829
// expressions into an array literal.
@@ -3834,10 +3837,7 @@ namespace ts {
38343837
if (compilerOptions.downlevelIteration) {
38353838
if (segments.length === 1) {
38363839
const firstSegment = segments[0];
3837-
if (isCallExpression(firstSegment)
3838-
&& isIdentifier(firstSegment.expression)
3839-
&& (getEmitFlags(firstSegment.expression) & EmitFlags.HelperName)
3840-
&& firstSegment.expression.escapedText === "___spread") {
3840+
if (isCallToHelper(firstSegment, "___spread" as __String)) {
38413841
return segments[0];
38423842
}
38433843
}
@@ -3846,17 +3846,33 @@ namespace ts {
38463846
}
38473847
else {
38483848
if (segments.length === 1) {
3849-
const firstElement = elements[0];
3850-
return needsUniqueCopy && isSpreadElement(firstElement) && firstElement.expression.kind !== SyntaxKind.ArrayLiteralExpression
3851-
? createArraySlice(segments[0])
3852-
: segments[0];
3849+
const firstSegment = segments[0];
3850+
if (!needsUniqueCopy
3851+
|| isPackedArrayLiteral(firstSegment)
3852+
|| isCallToHelper(firstSegment, "___spreadArrays" as __String)) {
3853+
return segments[0];
3854+
}
38533855
}
38543856

3855-
// Rewrite using the pattern <segment0>.concat(<segment1>, <segment2>, ...)
3856-
return createArrayConcat(segments.shift()!, segments);
3857+
return createSpreadArraysHelper(context, segments);
38573858
}
38583859
}
38593860

3861+
function isPackedElement(node: Expression) {
3862+
return !isOmittedExpression(node);
3863+
}
3864+
3865+
function isPackedArrayLiteral(node: Expression) {
3866+
return isArrayLiteralExpression(node) && every(node.elements, isPackedElement);
3867+
}
3868+
3869+
function isCallToHelper(firstSegment: Expression, helperName: __String) {
3870+
return isCallExpression(firstSegment)
3871+
&& isIdentifier(firstSegment.expression)
3872+
&& (getEmitFlags(firstSegment.expression) & EmitFlags.HelperName)
3873+
&& firstSegment.expression.escapedText === helperName;
3874+
}
3875+
38603876
function partitionSpread(node: Expression) {
38613877
return isSpreadElement(node)
38623878
? visitSpanOfSpreads

src/compiler/types.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3984,7 +3984,7 @@ namespace ts {
39843984
NotPrimitiveUnion = Any | Unknown | Enum | Void | Never | StructuredOrInstantiable,
39853985
// The following flags are aggregated during union and intersection type construction
39863986
/* @internal */
3987-
IncludesMask = Any | Unknown | Primitive | Never | Object | Union,
3987+
IncludesMask = Any | Unknown | Primitive | Never | Object | Union | NonPrimitive,
39883988
// The following flags are used for different purposes during union and intersection type construction
39893989
/* @internal */
39903990
IncludesStructuredOrInstantiable = TypeParameter,
@@ -5340,12 +5340,13 @@ namespace ts {
53405340
Values = 1 << 8, // __values (used by ES2015 for..of and yield* transformations)
53415341
Read = 1 << 9, // __read (used by ES2015 iterator destructuring transformation)
53425342
Spread = 1 << 10, // __spread (used by ES2015 array spread and argument list spread transformations)
5343-
Await = 1 << 11, // __await (used by ES2017 async generator transformation)
5344-
AsyncGenerator = 1 << 12, // __asyncGenerator (used by ES2017 async generator transformation)
5345-
AsyncDelegator = 1 << 13, // __asyncDelegator (used by ES2017 async generator yield* transformation)
5346-
AsyncValues = 1 << 14, // __asyncValues (used by ES2017 for..await..of transformation)
5347-
ExportStar = 1 << 15, // __exportStar (used by CommonJS/AMD/UMD module transformation)
5348-
MakeTemplateObject = 1 << 16, // __makeTemplateObject (used for constructing template string array objects)
5343+
SpreadArrays = 1 << 11, // __spreadArrays (used by ES2015 array spread and argument list spread transformations)
5344+
Await = 1 << 12, // __await (used by ES2017 async generator transformation)
5345+
AsyncGenerator = 1 << 13, // __asyncGenerator (used by ES2017 async generator transformation)
5346+
AsyncDelegator = 1 << 14, // __asyncDelegator (used by ES2017 async generator yield* transformation)
5347+
AsyncValues = 1 << 15, // __asyncValues (used by ES2017 for..await..of transformation)
5348+
ExportStar = 1 << 16, // __exportStar (used by CommonJS/AMD/UMD module transformation)
5349+
MakeTemplateObject = 1 << 17, // __makeTemplateObject (used for constructing template string array objects)
53495350
FirstEmitHelper = Extends,
53505351
LastEmitHelper = MakeTemplateObject,
53515352

tests/baselines/reference/argumentExpressionContextualTyping.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ baz(["string", 1, true, ...array]); // Error
1919
foo(o); // Error because x has an array type namely (string|number)[]
2020

2121
//// [argumentExpressionContextualTyping.js]
22+
var __spreadArrays = (this && this.__spreadArrays) || function () {
23+
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
24+
for (var r = Array(s), k = 0, i = 0; i < il; i++)
25+
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
26+
r[k] = a[j];
27+
return r;
28+
};
2229
// In a typed function call, argument expressions are contextually typed by their corresponding parameter types.
2330
function foo(_a) {
2431
var _b = _a.x, a = _b[0], b = _b[1], _c = _a.y, c = _c.c, d = _c.d, e = _c.e;
@@ -36,5 +43,5 @@ var tuple = ["string", 1, true];
3643
baz(tuple);
3744
baz(["string", 1, true]);
3845
baz(array); // Error
39-
baz(["string", 1, true].concat(array)); // Error
46+
baz(__spreadArrays(["string", 1, true], array)); // Error
4047
foo(o); // Error because x has an array type namely (string|number)[]

tests/baselines/reference/arrayLiteralExpressionContextualTyping.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ var spr2:[number, number, number] = [1, 2, 3, ...tup]; // Error
1616

1717

1818
//// [arrayLiteralExpressionContextualTyping.js]
19+
var __spreadArrays = (this && this.__spreadArrays) || function () {
20+
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
21+
for (var r = Array(s), k = 0, i = 0; i < il; i++)
22+
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
23+
r[k] = a[j];
24+
return r;
25+
};
1926
// In a contextually typed array literal expression containing no spread elements, an element expression at index N is contextually typed by
2027
// the type of the property with the numeric name N in the contextual type, if any, or otherwise
2128
// the numeric index type of the contextual type, if any.
@@ -26,6 +33,6 @@ var tup1 = [1, 2, 3, "string"];
2633
var tup2 = [1, 2, 3, "string"]; // Error
2734
// In a contextually typed array literal expression containing one or more spread elements,
2835
// an element expression at index N is contextually typed by the numeric index type of the contextual type, if any.
29-
var spr = [1, 2, 3].concat(array);
30-
var spr1 = [1, 2, 3].concat(tup);
31-
var spr2 = [1, 2, 3].concat(tup); // Error
36+
var spr = __spreadArrays([1, 2, 3], array);
37+
var spr1 = __spreadArrays([1, 2, 3], tup);
38+
var spr2 = __spreadArrays([1, 2, 3], tup); // Error

tests/baselines/reference/arrayLiteralSpread.js

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,27 @@ function f2() {
2424

2525

2626
//// [arrayLiteralSpread.js]
27+
var __spreadArrays = (this && this.__spreadArrays) || function () {
28+
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
29+
for (var r = Array(s), k = 0, i = 0; i < il; i++)
30+
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
31+
r[k] = a[j];
32+
return r;
33+
};
2734
function f0() {
2835
var a = [1, 2, 3];
29-
var a1 = a.slice();
30-
var a2 = [1].concat(a);
31-
var a3 = [1, 2].concat(a);
32-
var a4 = a.concat([1]);
33-
var a5 = a.concat([1, 2]);
34-
var a6 = [1, 2].concat(a, [1, 2]);
35-
var a7 = [1].concat(a, [2], a);
36-
var a8 = a.concat(a, a);
36+
var a1 = __spreadArrays(a);
37+
var a2 = __spreadArrays([1], a);
38+
var a3 = __spreadArrays([1, 2], a);
39+
var a4 = __spreadArrays(a, [1]);
40+
var a5 = __spreadArrays(a, [1, 2]);
41+
var a6 = __spreadArrays([1, 2], a, [1, 2]);
42+
var a7 = __spreadArrays([1], a, [2], a);
43+
var a8 = __spreadArrays(a, a, a);
3744
}
3845
function f1() {
3946
var a = [1, 2, 3];
40-
var b = ["hello"].concat(a, [true]);
47+
var b = __spreadArrays(["hello"], a, [true]);
4148
var b;
4249
}
4350
function f2() {

0 commit comments

Comments
 (0)