Skip to content

Commit 2cb2113

Browse files
committed
Merge branch 'master' into fix-implement-interface-with-extends-class
2 parents f9a55be + 364fce3 commit 2cb2113

112 files changed

Lines changed: 1302 additions & 762 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.

scripts/tslint/rules/nextLineRule.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ function walk(ctx: Lint.WalkContext<void>, checkCatch: boolean, checkElse: boole
5252
return;
5353
}
5454

55-
const tryClosingBrace = tryBlock.getLastToken(sourceFile);
56-
const catchKeyword = catchClause.getFirstToken(sourceFile);
55+
const tryClosingBrace = tryBlock.getLastToken(sourceFile)!;
56+
const catchKeyword = catchClause.getFirstToken(sourceFile)!;
5757
const tryClosingBraceLoc = sourceFile.getLineAndCharacterOfPosition(tryClosingBrace.getEnd());
5858
const catchKeywordLoc = sourceFile.getLineAndCharacterOfPosition(catchKeyword.getStart(sourceFile));
5959
if (tryClosingBraceLoc.line === catchKeywordLoc.line) {

scripts/tslint/rules/noInOperatorRule.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export class Rule extends Lint.Rules.AbstractRule {
1212
function walk(ctx: Lint.WalkContext<void>): void {
1313
ts.forEachChild(ctx.sourceFile, recur);
1414
function recur(node: ts.Node): void {
15-
if (node.kind === ts.SyntaxKind.InKeyword && node.parent!.kind === ts.SyntaxKind.BinaryExpression) {
15+
if (node.kind === ts.SyntaxKind.InKeyword && node.parent.kind === ts.SyntaxKind.BinaryExpression) {
1616
ctx.addFailureAtNode(node, Rule.FAILURE_STRING);
1717
}
1818
}

scripts/tslint/rules/noIncrementDecrementRule.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ function walk(ctx: Lint.WalkContext<void>): void {
2828
}
2929

3030
function check(node: ts.UnaryExpression): void {
31-
if (!isAllowedLocation(node.parent!)) {
31+
if (!isAllowedLocation(node.parent)) {
3232
ctx.addFailureAtNode(node, Rule.POSTFIX_FAILURE_STRING);
3333
}
3434
}
@@ -47,7 +47,7 @@ function isAllowedLocation(node: ts.Node): boolean {
4747
// Can be in a comma operator in a for statement (`for (let a = 0, b = 10; a < b; a++, b--)`)
4848
case ts.SyntaxKind.BinaryExpression:
4949
return (node as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.CommaToken &&
50-
node.parent!.kind === ts.SyntaxKind.ForStatement;
50+
node.parent.kind === ts.SyntaxKind.ForStatement;
5151

5252
default:
5353
return false;

src/compiler/checker.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10592,6 +10592,16 @@ namespace ts {
1059210592
else if (source.symbol && source.flags & TypeFlags.Object && globalObjectType === source) {
1059310593
reportError(Diagnostics.The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead);
1059410594
}
10595+
else if (getObjectFlags(source) & ObjectFlags.JsxAttributes && target.flags & TypeFlags.Intersection) {
10596+
const targetTypes = (target as IntersectionType).types;
10597+
const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes, errorNode);
10598+
const intrinsicClassAttributes = getJsxType(JsxNames.IntrinsicClassAttributes, errorNode);
10599+
if (intrinsicAttributes !== unknownType && intrinsicClassAttributes !== unknownType &&
10600+
(contains(targetTypes, intrinsicAttributes) || contains(targetTypes, intrinsicClassAttributes))) {
10601+
// do not report top error
10602+
return result;
10603+
}
10604+
}
1059510605
reportRelationError(headMessage, source, target);
1059610606
}
1059710607
return result;
@@ -16274,7 +16284,7 @@ namespace ts {
1627416284
return createJsxAttributesTypeFromAttributesProperty(node.parent, checkMode);
1627516285
}
1627616286

16277-
function getJsxType(name: __String, location: Node) {
16287+
function getJsxType(name: __String, location: Node | undefined) {
1627816288
const namespace = getJsxNamespaceAt(location);
1627916289
const exports = namespace && getExportsOfSymbol(namespace);
1628016290
const typeSymbol = exports && getSymbol(exports, name, SymbolFlags.Type);
@@ -16372,7 +16382,7 @@ namespace ts {
1637216382
return getSignatureInstantiation(signature, args, isJavascript);
1637316383
}
1637416384

16375-
function getJsxNamespaceAt(location: Node): Symbol {
16385+
function getJsxNamespaceAt(location: Node | undefined): Symbol {
1637616386
const namespaceName = getJsxNamespace(location);
1637716387
const resolvedNamespace = resolveName(location, namespaceName, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined, namespaceName, /*isUse*/ false);
1637816388
if (resolvedNamespace) {
@@ -20418,7 +20428,7 @@ namespace ts {
2041820428
if (propType.symbol && propType.symbol.flags & SymbolFlags.Class) {
2041920429
const name = prop.escapedName;
2042020430
const symbol = resolveName(prop.valueDeclaration, name, SymbolFlags.Type, undefined, name, /*isUse*/ false);
20421-
if (symbol) {
20431+
if (symbol && propType.symbol !== symbol) {
2042220432
grammarErrorOnNode(symbol.declarations[0], Diagnostics.Duplicate_identifier_0, unescapeLeadingUnderscores(name));
2042320433
return grammarErrorOnNode(prop.valueDeclaration, Diagnostics.Duplicate_identifier_0, unescapeLeadingUnderscores(name));
2042420434
}

src/compiler/transformers/esnext.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ namespace ts {
416416
createLogicalNot(getDone)
417417
),
418418
/*incrementor*/ undefined,
419-
/*statement*/ convertForOfStatementHead(node, createDownlevelAwait(getValue))
419+
/*statement*/ convertForOfStatementHead(node, getValue)
420420
),
421421
/*location*/ node
422422
),

src/compiler/transformers/generators.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3252,8 +3252,8 @@ namespace ts {
32523252
function step(op) {
32533253
if (f) throw new TypeError("Generator is already executing.");
32543254
while (_) try {
3255-
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
3256-
if (y = 0, t) op = [0, t.value];
3255+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
3256+
if (y = 0, t) op = [op[0] & 2, t.value];
32573257
switch (op[0]) {
32583258
case 0: case 1: t = op; break;
32593259
case 4: _.label++; return { value: op[1], done: false };

src/harness/fourslash.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,7 @@ namespace FourSlash {
868868
for (const entry of actualCompletions.entries) {
869869
if (actualByName.has(entry.name)) {
870870
// TODO: GH#23587
871-
if (entry.name !== "undefined" && entry.name !== "require") this.raiseError(`Duplicate completions for ${entry.name}`);
871+
if (entry.name !== "undefined" && entry.name !== "require") this.raiseError(`Duplicate (${actualCompletions.entries.filter(a => a.name === entry.name).length}) completions for ${entry.name}`);
872872
}
873873
else {
874874
actualByName.set(entry.name, entry);
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/// <reference path="..\harness.ts" />
2+
3+
namespace ts {
4+
declare var Symbol: SymbolConstructor;
5+
6+
describe("forAwaitOfEvaluation", () => {
7+
const sourceFile = vpath.combine(vfs.srcFolder, "source.ts");
8+
9+
function compile(sourceText: string, options?: CompilerOptions) {
10+
const fs = vfs.createFromFileSystem(Harness.IO, /*ignoreCase*/ false);
11+
fs.writeFileSync(sourceFile, sourceText);
12+
const compilerOptions: CompilerOptions = { target: ScriptTarget.ES5, module: ModuleKind.CommonJS, lib: ["lib.esnext.d.ts"], ...options };
13+
const host = new fakes.CompilerHost(fs, compilerOptions);
14+
return compiler.compileFiles(host, [sourceFile], compilerOptions);
15+
}
16+
17+
function noRequire(id: string) {
18+
throw new Error(`Module '${id}' could not be found.`);
19+
}
20+
21+
// Define a custom "Symbol" constructor to attach missing built-in symbols without
22+
// modifying the global "Symbol" constructor
23+
// tslint:disable-next-line:variable-name
24+
const FakeSymbol: SymbolConstructor = ((description?: string) => Symbol(description)) as any;
25+
(<any>FakeSymbol).prototype = Symbol.prototype;
26+
for (const key of Object.getOwnPropertyNames(Symbol)) {
27+
Object.defineProperty(FakeSymbol, key, Object.getOwnPropertyDescriptor(Symbol, key)!);
28+
}
29+
30+
// Add "asyncIterator" if missing
31+
if (!hasProperty(FakeSymbol, "asyncIterator")) Object.defineProperty(FakeSymbol, "asyncIterator", { value: Symbol.for("Symbol.asyncIterator"), configurable: true });
32+
33+
function evaluate(result: compiler.CompilationResult) {
34+
const output = result.getOutput(sourceFile, "js")!;
35+
assert.isDefined(output);
36+
37+
const evaluateText = `(function (module, exports, require, __dirname, __filename, Symbol) { ${output.text} })`;
38+
const evaluateThunk = eval(evaluateText) as (module: any, exports: any, require: (id: string) => any, dirname: string, filename: string, symbolConstructor: SymbolConstructor) => void;
39+
const module: { exports: any; } = { exports: {} };
40+
evaluateThunk(module, module.exports, noRequire, vpath.dirname(output.file), output.file, FakeSymbol);
41+
return module;
42+
}
43+
44+
it("sync (es5)", async () => {
45+
const module = evaluate(compile(`
46+
let i = 0;
47+
const iterator = {
48+
[Symbol.iterator]() { return this; },
49+
next() {
50+
switch (i++) {
51+
case 0: return { value: 1, done: false };
52+
case 1: return { value: Promise.resolve(2), done: false };
53+
case 2: return { value: new Promise<number>(resolve => setTimeout(resolve, 100, 3)), done: false };
54+
default: return { value: undefined: done: true };
55+
}
56+
}
57+
};
58+
export const output: any[] = [];
59+
export async function main() {
60+
for await (const item of iterator) {
61+
output.push(item);
62+
}
63+
}`));
64+
await module.exports.main();
65+
assert.strictEqual(module.exports.output[0], 1);
66+
assert.strictEqual(module.exports.output[1], 2);
67+
assert.strictEqual(module.exports.output[2], 3);
68+
});
69+
70+
it("sync (es2015)", async () => {
71+
const module = evaluate(compile(`
72+
let i = 0;
73+
const iterator = {
74+
[Symbol.iterator]() { return this; },
75+
next() {
76+
switch (i++) {
77+
case 0: return { value: 1, done: false };
78+
case 1: return { value: Promise.resolve(2), done: false };
79+
case 2: return { value: new Promise<number>(resolve => setTimeout(resolve, 100, 3)), done: false };
80+
default: return { value: undefined: done: true };
81+
}
82+
}
83+
};
84+
export const output: any[] = [];
85+
export async function main() {
86+
for await (const item of iterator) {
87+
output.push(item);
88+
}
89+
}`, { target: ScriptTarget.ES2015 }));
90+
await module.exports.main();
91+
assert.strictEqual(module.exports.output[0], 1);
92+
assert.strictEqual(module.exports.output[1], 2);
93+
assert.strictEqual(module.exports.output[2], 3);
94+
});
95+
96+
it("async (es5)", async () => {
97+
const module = evaluate(compile(`
98+
let i = 0;
99+
const iterator = {
100+
[Symbol.asyncIterator]() { return this; },
101+
async next() {
102+
switch (i++) {
103+
case 0: return { value: 1, done: false };
104+
case 1: return { value: Promise.resolve(2), done: false };
105+
case 2: return { value: new Promise<number>(resolve => setTimeout(resolve, 100, 3)), done: false };
106+
default: return { value: undefined: done: true };
107+
}
108+
}
109+
};
110+
export const output: any[] = [];
111+
export async function main() {
112+
for await (const item of iterator) {
113+
output.push(item);
114+
}
115+
}`));
116+
await module.exports.main();
117+
assert.strictEqual(module.exports.output[0], 1);
118+
assert.instanceOf(module.exports.output[1], Promise);
119+
assert.instanceOf(module.exports.output[2], Promise);
120+
});
121+
122+
it("async (es2015)", async () => {
123+
const module = evaluate(compile(`
124+
let i = 0;
125+
const iterator = {
126+
[Symbol.asyncIterator]() { return this; },
127+
async next() {
128+
switch (i++) {
129+
case 0: return { value: 1, done: false };
130+
case 1: return { value: Promise.resolve(2), done: false };
131+
case 2: return { value: new Promise<number>(resolve => setTimeout(resolve, 100, 3)), done: false };
132+
default: return { value: undefined: done: true };
133+
}
134+
}
135+
};
136+
export const output: any[] = [];
137+
export async function main() {
138+
for await (const item of iterator) {
139+
output.push(item);
140+
}
141+
}`, { target: ScriptTarget.ES2015 }));
142+
await module.exports.main();
143+
assert.strictEqual(module.exports.output[0], 1);
144+
assert.instanceOf(module.exports.output[1], Promise);
145+
assert.instanceOf(module.exports.output[2], Promise);
146+
});
147+
});
148+
}

src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,6 +2394,15 @@
23942394
</Str>
23952395
<Disp Icon="Str" />
23962396
</Item>
2397+
<Item ItemId=";Class_name_cannot_be_Object_when_targeting_ES5_with_module_0_2725" ItemType="0" PsrId="306" Leaf="true">
2398+
<Str Cat="Text">
2399+
<Val><![CDATA[Class name cannot be 'Object' when targeting ES5 with module {0}.]]></Val>
2400+
<Tgt Cat="Text" Stat="Loc" Orig="New">
2401+
<Val><![CDATA[使用模块 {0} 将目标设置为 ES5 时,类名称不能为 "Object"。]]></Val>
2402+
</Tgt>
2403+
</Str>
2404+
<Disp Icon="Str" />
2405+
</Item>
23972406
<Item ItemId=";Class_static_side_0_incorrectly_extends_base_class_static_side_1_2417" ItemType="0" PsrId="306" Leaf="true">
23982407
<Str Cat="Text">
23992408
<Val><![CDATA[Class static side '{0}' incorrectly extends base class static side '{1}'.]]></Val>
@@ -2559,6 +2568,9 @@
25592568
<Item ItemId=";Convert_0_to_mapped_object_type_95055" ItemType="0" PsrId="306" Leaf="true">
25602569
<Str Cat="Text">
25612570
<Val><![CDATA[Convert '{0}' to mapped object type]]></Val>
2571+
<Tgt Cat="Text" Stat="Loc" Orig="New">
2572+
<Val><![CDATA[将“{0}”转换为映射对象类型]]></Val>
2573+
</Tgt>
25622574
</Str>
25632575
<Disp Icon="Str" />
25642576
</Item>

src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,6 +2394,15 @@
23942394
</Str>
23952395
<Disp Icon="Str" />
23962396
</Item>
2397+
<Item ItemId=";Class_name_cannot_be_Object_when_targeting_ES5_with_module_0_2725" ItemType="0" PsrId="306" Leaf="true">
2398+
<Str Cat="Text">
2399+
<Val><![CDATA[Class name cannot be 'Object' when targeting ES5 with module {0}.]]></Val>
2400+
<Tgt Cat="Text" Stat="Loc" Orig="New">
2401+
<Val><![CDATA[當目標為具有模組 {0} 的 ES5 時,類別名稱不可為 'Object'。]]></Val>
2402+
</Tgt>
2403+
</Str>
2404+
<Disp Icon="Str" />
2405+
</Item>
23972406
<Item ItemId=";Class_static_side_0_incorrectly_extends_base_class_static_side_1_2417" ItemType="0" PsrId="306" Leaf="true">
23982407
<Str Cat="Text">
23992408
<Val><![CDATA[Class static side '{0}' incorrectly extends base class static side '{1}'.]]></Val>
@@ -2556,6 +2565,15 @@
25562565
</Str>
25572566
<Disp Icon="Str" />
25582567
</Item>
2568+
<Item ItemId=";Convert_0_to_mapped_object_type_95055" ItemType="0" PsrId="306" Leaf="true">
2569+
<Str Cat="Text">
2570+
<Val><![CDATA[Convert '{0}' to mapped object type]]></Val>
2571+
<Tgt Cat="Text" Stat="Loc" Orig="New">
2572+
<Val><![CDATA[將 '{0}' 轉換為對應的物件類型]]></Val>
2573+
</Tgt>
2574+
</Str>
2575+
<Disp Icon="Str" />
2576+
</Item>
25592577
<Item ItemId=";Convert_all_constructor_functions_to_classes_95045" ItemType="0" PsrId="306" Leaf="true">
25602578
<Str Cat="Text">
25612579
<Val><![CDATA[Convert all constructor functions to classes]]></Val>

0 commit comments

Comments
 (0)