Added es5 conformance tests for async function declarations. Add ability to treat some statements as if they were prologue directives.

This commit is contained in:
Ron Buckton 2016-06-27 15:26:33 -07:00
parent 5b2e11c5d0
commit 48a9562e41
57 changed files with 739 additions and 74 deletions

View File

@ -1649,28 +1649,36 @@ namespace ts {
* @param target: result statements array
* @param source: origin statements array
* @param ensureUseStrict: boolean determining whether the function need to add prologue-directives
* @param visitor: Optional callback used to visit any custom prologue directives.
*/
export function addPrologueDirectives(target: Statement[], source: Statement[], ensureUseStrict?: boolean): number {
export function addPrologueDirectives(target: Statement[], source: Statement[], ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult<Node>): number {
Debug.assert(target.length === 0, "PrologueDirectives should be at the first statement in the target statements array");
let foundUseStrict = false;
for (let i = 0; i < source.length; i++) {
if (isPrologueDirective(source[i])) {
if (isUseStrictPrologue(source[i] as ExpressionStatement)) {
let statementOffset = 0;
const numStatements = source.length;
while (statementOffset < numStatements) {
const statement = source[statementOffset];
if (isPrologueDirective(statement)) {
if (isUseStrictPrologue(statement as ExpressionStatement)) {
foundUseStrict = true;
}
target.push(source[i]);
target.push(statement);
}
else {
if (ensureUseStrict && !foundUseStrict) {
target.push(startOnNewLine(createStatement(createLiteral("use strict"))));
foundUseStrict = true;
}
if (statement.emitFlags & NodeEmitFlags.CustomPrologue) {
target.push(visitor ? visitNode(statement, visitor, isStatement) : statement);
}
else {
break;
}
return i;
}
statementOffset++;
}
return source.length;
return statementOffset;
}
/**

View File

@ -930,21 +930,27 @@ namespace ts {
// of an initializer, we must emit that expression to preserve side effects.
if (name.elements.length > 0) {
statements.push(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(
flattenParameterDestructuring(context, parameter, temp, visitor)
)
setNodeEmitFlags(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(
flattenParameterDestructuring(context, parameter, temp, visitor)
)
),
NodeEmitFlags.CustomPrologue
)
);
}
else if (initializer) {
statements.push(
createStatement(
createAssignment(
temp,
visitNode(initializer, visitor, isExpression)
)
setNodeEmitFlags(
createStatement(
createAssignment(
temp,
visitNode(initializer, visitor, isExpression)
)
),
NodeEmitFlags.CustomPrologue
)
);
}
@ -981,7 +987,7 @@ namespace ts {
/*location*/ parameter
);
statement.startsOnNewLine = true;
setNodeEmitFlags(statement, NodeEmitFlags.NoTokenSourceMaps | NodeEmitFlags.NoTrailingSourceMap);
setNodeEmitFlags(statement, NodeEmitFlags.NoTokenSourceMaps | NodeEmitFlags.NoTrailingSourceMap | NodeEmitFlags.CustomPrologue);
statements.push(statement);
}
@ -1023,16 +1029,19 @@ namespace ts {
// var param = [];
statements.push(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
createVariableDeclaration(
declarationName,
/*type*/ undefined,
createArrayLiteral([])
)
]),
/*location*/ parameter
setNodeEmitFlags(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
createVariableDeclaration(
declarationName,
/*type*/ undefined,
createArrayLiteral([])
)
]),
/*location*/ parameter
),
NodeEmitFlags.CustomPrologue
)
);
@ -1065,7 +1074,7 @@ namespace ts {
])
);
setNodeEmitFlags(forStatement, NodeEmitFlags.SourceMapAdjustRestParameterLoop);
setNodeEmitFlags(forStatement, NodeEmitFlags.SourceMapAdjustRestParameterLoop | NodeEmitFlags.CustomPrologue);
startOnNewLine(forStatement);
statements.push(forStatement);
}
@ -1090,7 +1099,7 @@ namespace ts {
])
);
setNodeEmitFlags(captureThisStatement, NodeEmitFlags.NoComments);
setNodeEmitFlags(captureThisStatement, NodeEmitFlags.NoComments | NodeEmitFlags.CustomPrologue);
setSourceMapRange(captureThisStatement, node);
statements.push(captureThisStatement);
}
@ -1347,7 +1356,7 @@ namespace ts {
if (isBlock(body)) {
// ensureUseStrict is false because no new prologue-directive should be added.
// addPrologueDirectives will simply put already-existing directives at the beginning of the target statement-array
statementOffset = addPrologueDirectives(statements, body.statements, /*ensureUseStrict*/ false);
statementOffset = addPrologueDirectives(statements, body.statements, /*ensureUseStrict*/ false, visitor);
}
addCaptureThisForNodeIfNeeded(statements, node);

View File

@ -309,10 +309,7 @@ namespace ts {
*/
function visitor(node: Node): VisitResult<Node> {
const transformFlags = node.transformFlags;
if (transformFlags & TransformFlags.ContainsYield) {
return visitJavaScriptContainingYield(node);
}
else if (inStatementContainingYield) {
if (inStatementContainingYield) {
return visitJavaScriptInStatementContainingYield(node);
}
else if (inGeneratorFunctionBody) {
@ -329,34 +326,6 @@ namespace ts {
}
}
/**
* Visits a node that contains a YieldExpression.
*
* @param node The node to visit.
*/
function visitJavaScriptContainingYield(node: Node): VisitResult<Node> {
switch (node.kind) {
case SyntaxKind.BinaryExpression:
return visitBinaryExpression(<BinaryExpression>node);
case SyntaxKind.ConditionalExpression:
return visitConditionalExpression(<ConditionalExpression>node);
case SyntaxKind.YieldExpression:
return visitYieldExpression(<YieldExpression>node);
case SyntaxKind.ArrayLiteralExpression:
return visitArrayLiteralExpression(<ArrayLiteralExpression>node);
case SyntaxKind.ObjectLiteralExpression:
return visitObjectLiteralExpression(<ObjectLiteralExpression>node);
case SyntaxKind.ElementAccessExpression:
return visitElementAccessExpression(<ElementAccessExpression>node);
case SyntaxKind.CallExpression:
return visitCallExpression(<CallExpression>node);
case SyntaxKind.NewExpression:
return visitNewExpression(<NewExpression>node);
default:
return visitJavaScriptInStatementContainingYield(node);
}
}
/**
* Visits a node that is contained within a statement that contains yield.
*
@ -404,7 +373,10 @@ namespace ts {
case SyntaxKind.ReturnStatement:
return visitReturnStatement(<ReturnStatement>node);
default:
if (node.transformFlags & (TransformFlags.ContainsGenerator | TransformFlags.ContainsYield | TransformFlags.ContainsHoistedDeclarationOrCompletion)) {
if (node.transformFlags & TransformFlags.ContainsYield) {
return visitJavaScriptContainingYield(node);
}
else if (node.transformFlags & (TransformFlags.ContainsGenerator | TransformFlags.ContainsHoistedDeclarationOrCompletion)) {
return visitEachChild(node, visitor, context);
}
else {
@ -413,6 +385,34 @@ namespace ts {
}
}
/**
* Visits a node that contains a YieldExpression.
*
* @param node The node to visit.
*/
function visitJavaScriptContainingYield(node: Node): VisitResult<Node> {
switch (node.kind) {
case SyntaxKind.BinaryExpression:
return visitBinaryExpression(<BinaryExpression>node);
case SyntaxKind.ConditionalExpression:
return visitConditionalExpression(<ConditionalExpression>node);
case SyntaxKind.YieldExpression:
return visitYieldExpression(<YieldExpression>node);
case SyntaxKind.ArrayLiteralExpression:
return visitArrayLiteralExpression(<ArrayLiteralExpression>node);
case SyntaxKind.ObjectLiteralExpression:
return visitObjectLiteralExpression(<ObjectLiteralExpression>node);
case SyntaxKind.ElementAccessExpression:
return visitElementAccessExpression(<ElementAccessExpression>node);
case SyntaxKind.CallExpression:
return visitCallExpression(<CallExpression>node);
case SyntaxKind.NewExpression:
return visitNewExpression(<NewExpression>node);
default:
return visitEachChild(node, visitor, context);
}
}
/**
* Visits a generator function.
*
@ -572,7 +572,7 @@ namespace ts {
operationLocations = undefined;
state = createTempVariable(/*recordTempVariable*/ undefined);
const statementOffset = addPrologueDirectives(statements, body.statements);
const statementOffset = addPrologueDirectives(statements, body.statements, /*ensureUseStrict*/ false, visitor);
// Build the generator
startLexicalEnvironment();

View File

@ -84,7 +84,7 @@ namespace ts {
startLexicalEnvironment();
const statements: Statement[] = [];
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict);
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, visitor);
addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset));
addRange(statements, endLexicalEnvironment());
addExportEqualsIfNeeded(statements, /*emitAsReturn*/ false);
@ -203,7 +203,7 @@ namespace ts {
startLexicalEnvironment();
const statements: Statement[] = [];
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict);
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, visitor);
// Visit each statement of the module body.
addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset));

View File

@ -194,7 +194,7 @@ namespace ts {
startLexicalEnvironment();
// Add any prologue directives.
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict);
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, visitSourceElement);
// var __moduleName = context_1 && context_1.id;
addNode(statements,

View File

@ -431,7 +431,7 @@ namespace ts {
&& (isExternalModule(node) || compilerOptions.isolatedModules)) {
startLexicalEnvironment();
const statements: Statement[] = [];
const statementOffset = addPrologueDirectives(statements, node.statements);
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ false, visitor);
const externalHelpersModuleName = createUniqueName(externalHelpersModuleNameText);
const externalHelpersModuleImport = createImportDeclaration(
createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)),
@ -933,7 +933,7 @@ namespace ts {
if (ctor.body) {
const statements = ctor.body.statements;
// add prologue directives to the list (if any)
const index = addPrologueDirectives(result, statements);
const index = addPrologueDirectives(result, statements, /*ensureUseStrict*/ false, visitor);
if (index === statements.length) {
// list contains nothing but prologue directives (or empty) - exit
return index;
@ -2235,7 +2235,7 @@ namespace ts {
if (!isArrowFunction) {
const statements: Statement[] = [];
const statementOffset = addPrologueDirectives(statements, (<Block>node.body).statements);
const statementOffset = addPrologueDirectives(statements, (<Block>node.body).statements, /*ensureUseStrict*/ false, visitor);
statements.push(
createReturn(
createAwaiterHelper(

View File

@ -3064,6 +3064,7 @@ namespace ts {
Indented = 1 << 19, // Adds an explicit extra indentation level for class and function bodies when printing (used to match old emitter).
AsyncFunctionBody = 1 << 20,
ReuseTempVariableScope = 1 << 21, // Reuse the existing temp variable scope during emit.
CustomPrologue = 1 << 22, // Treat the statement as if it were a prologue directive (NOTE: Prologue directives are *not* transformed).
// SourceMap Specialization.
// TODO(rbuckton): These should be removed once source maps are aligned with the old

View File

@ -0,0 +1,26 @@
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,20): error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,30): error TS1109: Expression expected.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,33): error TS1138: Parameter declaration expected.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,33): error TS2304: Cannot find name 'await'.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,38): error TS1005: ';' expected.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,39): error TS1128: Declaration or statement expected.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,53): error TS1109: Expression expected.
==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts (7 errors) ====
async function foo(a = await => await): Promise<void> {
~~~~~~~~~
!!! error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
~~
!!! error TS1109: Expression expected.
~~~~~
!!! error TS1138: Parameter declaration expected.
~~~~~
!!! error TS2304: Cannot find name 'await'.
~
!!! error TS1005: ';' expected.
~
!!! error TS1128: Declaration or statement expected.
~
!!! error TS1109: Expression expected.
}

View File

@ -0,0 +1,7 @@
//// [asyncFunctionDeclaration10_es5.ts]
async function foo(a = await => await): Promise<void> {
}
//// [asyncFunctionDeclaration10_es5.js]
await;
Promise < void > {};

View File

@ -0,0 +1,12 @@
//// [asyncFunctionDeclaration11_es5.ts]
async function await(): Promise<void> {
}
//// [asyncFunctionDeclaration11_es5.js]
function await() {
return __awaiter(this, void 0, Promise, function () {
return __generator(function (_a) {
return [2 /*return*/];
});
});
}

View File

@ -0,0 +1,5 @@
=== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration11_es5.ts ===
async function await(): Promise<void> {
>await : Symbol(await, Decl(asyncFunctionDeclaration11_es5.ts, 0, 0))
>Promise : Symbol(Promise, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
}

View File

@ -0,0 +1,5 @@
=== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration11_es5.ts ===
async function await(): Promise<void> {
>await : () => Promise<void>
>Promise : Promise<T>
}

View File

@ -0,0 +1,16 @@
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration12_es5.ts(1,24): error TS1005: '(' expected.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration12_es5.ts(1,29): error TS1005: '=' expected.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration12_es5.ts(1,33): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration12_es5.ts(1,47): error TS1005: '=>' expected.
==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration12_es5.ts (4 errors) ====
var v = async function await(): Promise<void> { }
~~~~~
!!! error TS1005: '(' expected.
~
!!! error TS1005: '=' expected.
~~~~~~~~~~~~~
!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value.
~
!!! error TS1005: '=>' expected.

View File

@ -0,0 +1,5 @@
//// [asyncFunctionDeclaration12_es5.ts]
var v = async function await(): Promise<void> { }
//// [asyncFunctionDeclaration12_es5.js]
var v = , await = function () { };

View File

@ -0,0 +1,11 @@
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration13_es5.ts(3,11): error TS2304: Cannot find name 'await'.
==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration13_es5.ts (1 errors) ====
async function foo(): Promise<void> {
// Legal to use 'await' in a type context.
var v: await;
~~~~~
!!! error TS2304: Cannot find name 'await'.
}

View File

@ -0,0 +1,16 @@
//// [asyncFunctionDeclaration13_es5.ts]
async function foo(): Promise<void> {
// Legal to use 'await' in a type context.
var v: await;
}
//// [asyncFunctionDeclaration13_es5.js]
function foo() {
return __awaiter(this, void 0, Promise, function () {
var v;
return __generator(function (_a) {
return [2 /*return*/];
});
});
}

View File

@ -0,0 +1,13 @@
//// [asyncFunctionDeclaration14_es5.ts]
async function foo(): Promise<void> {
return;
}
//// [asyncFunctionDeclaration14_es5.js]
function foo() {
return __awaiter(this, void 0, Promise, function () {
return __generator(function (_a) {
return [2 /*return*/];
});
});
}

View File

@ -0,0 +1,7 @@
=== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration14_es5.ts ===
async function foo(): Promise<void> {
>foo : Symbol(foo, Decl(asyncFunctionDeclaration14_es5.ts, 0, 0))
>Promise : Symbol(Promise, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
return;
}

View File

@ -0,0 +1,7 @@
=== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration14_es5.ts ===
async function foo(): Promise<void> {
>foo : () => Promise<void>
>Promise : Promise<T>
return;
}

View File

@ -0,0 +1,59 @@
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(6,16): error TS1055: Type '{}' is not a valid async function return type.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(7,16): error TS1055: Type 'any' is not a valid async function return type.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(8,16): error TS1055: Type 'number' is not a valid async function return type.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(9,16): error TS1055: Type 'PromiseLike' is not a valid async function return type.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(10,16): error TS1055: Type 'typeof Thenable' is not a valid async function return type.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(10,16): error TS1055: Type 'typeof Thenable' is not a valid async function return type.
Type 'Thenable' is not assignable to type 'PromiseLike<any>'.
Types of property 'then' are incompatible.
Type '() => void' is not assignable to type '{ <TResult>(onfulfilled?: (value: any) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): PromiseLike<TResult>; <TResult>(onfulfilled?: (value: any) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): PromiseLike<TResult>; }'.
Type 'void' is not assignable to type 'PromiseLike<any>'.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(17,16): error TS1059: Return expression in async function does not have a valid callable 'then' member.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(23,25): error TS1058: Operand for 'await' does not have a valid callable 'then' member.
==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts (8 errors) ====
declare class Thenable { then(): void; }
declare let a: any;
declare let obj: { then: string; };
declare let thenable: Thenable;
async function fn1() { } // valid: Promise<void>
async function fn2(): { } { } // error
~~~
!!! error TS1055: Type '{}' is not a valid async function return type.
async function fn3(): any { } // error
~~~
!!! error TS1055: Type 'any' is not a valid async function return type.
async function fn4(): number { } // error
~~~
!!! error TS1055: Type 'number' is not a valid async function return type.
async function fn5(): PromiseLike<void> { } // error
~~~
!!! error TS1055: Type 'PromiseLike' is not a valid async function return type.
async function fn6(): Thenable { } // error
~~~
!!! error TS1055: Type 'typeof Thenable' is not a valid async function return type.
~~~
!!! error TS1055: Type 'typeof Thenable' is not a valid async function return type.
!!! error TS1055: Type 'Thenable' is not assignable to type 'PromiseLike<any>'.
!!! error TS1055: Types of property 'then' are incompatible.
!!! error TS1055: Type '() => void' is not assignable to type '{ <TResult>(onfulfilled?: (value: any) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): PromiseLike<TResult>; <TResult>(onfulfilled?: (value: any) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): PromiseLike<TResult>; }'.
!!! error TS1055: Type 'void' is not assignable to type 'PromiseLike<any>'.
async function fn7() { return; } // valid: Promise<void>
async function fn8() { return 1; } // valid: Promise<number>
async function fn9() { return null; } // valid: Promise<any>
async function fn10() { return undefined; } // valid: Promise<any>
async function fn11() { return a; } // valid: Promise<any>
async function fn12() { return obj; } // valid: Promise<{ then: string; }>
async function fn13() { return thenable; } // error
~~~~
!!! error TS1059: Return expression in async function does not have a valid callable 'then' member.
async function fn14() { await 1; } // valid: Promise<void>
async function fn15() { await null; } // valid: Promise<void>
async function fn16() { await undefined; } // valid: Promise<void>
async function fn17() { await a; } // valid: Promise<void>
async function fn18() { await obj; } // valid: Promise<void>
async function fn19() { await thenable; } // error
~~~~~~~~~~~~~~
!!! error TS1058: Operand for 'await' does not have a valid callable 'then' member.

View File

@ -0,0 +1,152 @@
//// [asyncFunctionDeclaration15_es5.ts]
declare class Thenable { then(): void; }
declare let a: any;
declare let obj: { then: string; };
declare let thenable: Thenable;
async function fn1() { } // valid: Promise<void>
async function fn2(): { } { } // error
async function fn3(): any { } // error
async function fn4(): number { } // error
async function fn5(): PromiseLike<void> { } // error
async function fn6(): Thenable { } // error
async function fn7() { return; } // valid: Promise<void>
async function fn8() { return 1; } // valid: Promise<number>
async function fn9() { return null; } // valid: Promise<any>
async function fn10() { return undefined; } // valid: Promise<any>
async function fn11() { return a; } // valid: Promise<any>
async function fn12() { return obj; } // valid: Promise<{ then: string; }>
async function fn13() { return thenable; } // error
async function fn14() { await 1; } // valid: Promise<void>
async function fn15() { await null; } // valid: Promise<void>
async function fn16() { await undefined; } // valid: Promise<void>
async function fn17() { await a; } // valid: Promise<void>
async function fn18() { await obj; } // valid: Promise<void>
async function fn19() { await thenable; } // error
//// [asyncFunctionDeclaration15_es5.js]
function fn1() {
return __awaiter(this, void 0, void 0, function () { return __generator(function (_a) {
return [2 /*return*/];
}); });
} // valid: Promise<void>
function fn2() {
return __awaiter(this, void 0, void 0, function () { return __generator(function (_a) {
return [2 /*return*/];
}); });
} // error
function fn3() {
return __awaiter(this, void 0, void 0, function () { return __generator(function (_a) {
return [2 /*return*/];
}); });
} // error
function fn4() {
return __awaiter(this, void 0, void 0, function () { return __generator(function (_a) {
return [2 /*return*/];
}); });
} // error
function fn5() {
return __awaiter(this, void 0, PromiseLike, function () { return __generator(function (_a) {
return [2 /*return*/];
}); });
} // error
function fn6() {
return __awaiter(this, void 0, Thenable, function () { return __generator(function (_a) {
return [2 /*return*/];
}); });
} // error
function fn7() {
return __awaiter(this, void 0, void 0, function () { return __generator(function (_a) {
return [2 /*return*/];
}); });
} // valid: Promise<void>
function fn8() {
return __awaiter(this, void 0, void 0, function () { return __generator(function (_a) {
return [2 /*return*/, 1];
}); });
} // valid: Promise<number>
function fn9() {
return __awaiter(this, void 0, void 0, function () { return __generator(function (_a) {
return [2 /*return*/, null];
}); });
} // valid: Promise<any>
function fn10() {
return __awaiter(this, void 0, void 0, function () { return __generator(function (_a) {
return [2 /*return*/, undefined];
}); });
} // valid: Promise<any>
function fn11() {
return __awaiter(this, void 0, void 0, function () { return __generator(function (_a) {
return [2 /*return*/, a];
}); });
} // valid: Promise<any>
function fn12() {
return __awaiter(this, void 0, void 0, function () { return __generator(function (_a) {
return [2 /*return*/, obj];
}); });
} // valid: Promise<{ then: string; }>
function fn13() {
return __awaiter(this, void 0, void 0, function () { return __generator(function (_a) {
return [2 /*return*/, thenable];
}); });
} // error
function fn14() {
return __awaiter(this, void 0, void 0, function () { return __generator(function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, 1];
case 1:
_a.sent();
return [2 /*return*/];
}
}); });
} // valid: Promise<void>
function fn15() {
return __awaiter(this, void 0, void 0, function () { return __generator(function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, null];
case 1:
_a.sent();
return [2 /*return*/];
}
}); });
} // valid: Promise<void>
function fn16() {
return __awaiter(this, void 0, void 0, function () { return __generator(function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, undefined];
case 1:
_a.sent();
return [2 /*return*/];
}
}); });
} // valid: Promise<void>
function fn17() {
return __awaiter(this, void 0, void 0, function () { return __generator(function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, a];
case 1:
_a.sent();
return [2 /*return*/];
}
}); });
} // valid: Promise<void>
function fn18() {
return __awaiter(this, void 0, void 0, function () { return __generator(function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, obj];
case 1:
_a.sent();
return [2 /*return*/];
}
}); });
} // valid: Promise<void>
function fn19() {
return __awaiter(this, void 0, void 0, function () { return __generator(function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, thenable];
case 1:
_a.sent();
return [2 /*return*/];
}
}); });
} // error

View File

@ -0,0 +1,12 @@
//// [asyncFunctionDeclaration1_es5.ts]
async function foo(): Promise<void> {
}
//// [asyncFunctionDeclaration1_es5.js]
function foo() {
return __awaiter(this, void 0, Promise, function () {
return __generator(function (_a) {
return [2 /*return*/];
});
});
}

View File

@ -0,0 +1,5 @@
=== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration1_es5.ts ===
async function foo(): Promise<void> {
>foo : Symbol(foo, Decl(asyncFunctionDeclaration1_es5.ts, 0, 0))
>Promise : Symbol(Promise, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
}

View File

@ -0,0 +1,5 @@
=== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration1_es5.ts ===
async function foo(): Promise<void> {
>foo : () => Promise<void>
>Promise : Promise<T>
}

View File

@ -0,0 +1,7 @@
//// [asyncFunctionDeclaration2_es5.ts]
function f(await) {
}
//// [asyncFunctionDeclaration2_es5.js]
function f(await) {
}

View File

@ -0,0 +1,5 @@
=== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration2_es5.ts ===
function f(await) {
>f : Symbol(f, Decl(asyncFunctionDeclaration2_es5.ts, 0, 0))
>await : Symbol(await, Decl(asyncFunctionDeclaration2_es5.ts, 0, 11))
}

View File

@ -0,0 +1,5 @@
=== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration2_es5.ts ===
function f(await) {
>f : (await: any) => void
>await : any
}

View File

@ -0,0 +1,8 @@
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration3_es5.ts(1,20): error TS2372: Parameter 'await' cannot be referenced in its initializer.
==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration3_es5.ts (1 errors) ====
function f(await = await) {
~~~~~
!!! error TS2372: Parameter 'await' cannot be referenced in its initializer.
}

View File

@ -0,0 +1,8 @@
//// [asyncFunctionDeclaration3_es5.ts]
function f(await = await) {
}
//// [asyncFunctionDeclaration3_es5.js]
function f(await) {
if (await === void 0) { await = await; }
}

View File

@ -0,0 +1,7 @@
//// [asyncFunctionDeclaration4_es5.ts]
function await() {
}
//// [asyncFunctionDeclaration4_es5.js]
function await() {
}

View File

@ -0,0 +1,4 @@
=== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration4_es5.ts ===
function await() {
>await : Symbol(await, Decl(asyncFunctionDeclaration4_es5.ts, 0, 0))
}

View File

@ -0,0 +1,4 @@
=== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration4_es5.ts ===
function await() {
>await : () => void
}

View File

@ -0,0 +1,20 @@
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5_es5.ts(1,20): error TS1138: Parameter declaration expected.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5_es5.ts(1,20): error TS2304: Cannot find name 'await'.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5_es5.ts(1,25): error TS1005: ';' expected.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5_es5.ts(1,26): error TS1128: Declaration or statement expected.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5_es5.ts(1,40): error TS1109: Expression expected.
==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5_es5.ts (5 errors) ====
async function foo(await): Promise<void> {
~~~~~
!!! error TS1138: Parameter declaration expected.
~~~~~
!!! error TS2304: Cannot find name 'await'.
~
!!! error TS1005: ';' expected.
~
!!! error TS1128: Declaration or statement expected.
~
!!! error TS1109: Expression expected.
}

View File

@ -0,0 +1,7 @@
//// [asyncFunctionDeclaration5_es5.ts]
async function foo(await): Promise<void> {
}
//// [asyncFunctionDeclaration5_es5.js]
await;
Promise < void > {};

View File

@ -0,0 +1,11 @@
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration6_es5.ts(1,24): error TS2524: 'await' expressions cannot be used in a parameter initializer.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration6_es5.ts(1,29): error TS1109: Expression expected.
==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration6_es5.ts (2 errors) ====
async function foo(a = await): Promise<void> {
~~~~~
!!! error TS2524: 'await' expressions cannot be used in a parameter initializer.
~
!!! error TS1109: Expression expected.
}

View File

@ -0,0 +1,13 @@
//// [asyncFunctionDeclaration6_es5.ts]
async function foo(a = await): Promise<void> {
}
//// [asyncFunctionDeclaration6_es5.js]
function foo(a) {
if (a === void 0) { a = yield ; }
return __awaiter(this, void 0, Promise, function () {
return __generator(function (_a) {
return [2 /*return*/];
});
});
}

View File

@ -0,0 +1,14 @@
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration7_es5.ts(3,26): error TS2524: 'await' expressions cannot be used in a parameter initializer.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration7_es5.ts(3,31): error TS1109: Expression expected.
==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration7_es5.ts (2 errors) ====
async function bar(): Promise<void> {
// 'await' here is an identifier, and not a yield expression.
async function foo(a = await): Promise<void> {
~~~~~
!!! error TS2524: 'await' expressions cannot be used in a parameter initializer.
~
!!! error TS1109: Expression expected.
}
}

View File

@ -0,0 +1,24 @@
//// [asyncFunctionDeclaration7_es5.ts]
async function bar(): Promise<void> {
// 'await' here is an identifier, and not a yield expression.
async function foo(a = await): Promise<void> {
}
}
//// [asyncFunctionDeclaration7_es5.js]
function bar() {
return __awaiter(this, void 0, Promise, function () {
// 'await' here is an identifier, and not a yield expression.
function foo(a) {
if (a === void 0) { a = yield ; }
return __awaiter(this, void 0, Promise, function () {
return __generator(function (_a) {
return [2 /*return*/];
});
});
}
return __generator(function (_a) {
return [2 /*return*/];
});
});
}

View File

@ -0,0 +1,10 @@
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration8_es5.ts(1,12): error TS2304: Cannot find name 'await'.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration8_es5.ts(1,20): error TS2304: Cannot find name 'foo'.
==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration8_es5.ts (2 errors) ====
var v = { [await]: foo }
~~~~~
!!! error TS2304: Cannot find name 'await'.
~~~
!!! error TS2304: Cannot find name 'foo'.

View File

@ -0,0 +1,6 @@
//// [asyncFunctionDeclaration8_es5.ts]
var v = { [await]: foo }
//// [asyncFunctionDeclaration8_es5.js]
var v = (_a = {}, _a[await] = foo, _a);
var _a;

View File

@ -0,0 +1,9 @@
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration9_es5.ts(2,19): error TS1109: Expression expected.
==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration9_es5.ts (1 errors) ====
async function foo(): Promise<void> {
var v = { [await]: foo }
~
!!! error TS1109: Expression expected.
}

View File

@ -0,0 +1,21 @@
//// [asyncFunctionDeclaration9_es5.ts]
async function foo(): Promise<void> {
var v = { [await]: foo }
}
//// [asyncFunctionDeclaration9_es5.js]
function foo() {
return __awaiter(this, void 0, Promise, function () {
var v, _a;
return __generator(function (_b) {
switch (_b.label) {
case 0:
_a = {};
return [4 /*yield*/, ];
case 1:
v = (_a[_b.sent()] = foo, _a);
return [2 /*return*/];
}
});
});
}

View File

@ -0,0 +1,5 @@
// @target: ES5
// @lib: es5,es2015.promise
// @noEmitHelpers: true
async function foo(a = await => await): Promise<void> {
}

View File

@ -0,0 +1,5 @@
// @target: ES5
// @lib: es5,es2015.promise
// @noEmitHelpers: true
async function await(): Promise<void> {
}

View File

@ -0,0 +1,4 @@
// @target: ES5
// @lib: es5,es2015.promise
// @noEmitHelpers: true
var v = async function await(): Promise<void> { }

View File

@ -0,0 +1,7 @@
// @target: ES5
// @lib: es5,es2015.promise
// @noEmitHelpers: true
async function foo(): Promise<void> {
// Legal to use 'await' in a type context.
var v: await;
}

View File

@ -0,0 +1,6 @@
// @target: ES5
// @lib: es5,es2015.promise
// @noEmitHelpers: true
async function foo(): Promise<void> {
return;
}

View File

@ -0,0 +1,26 @@
// @target: ES5
// @lib: es5,es2015.promise
// @noEmitHelpers: true
declare class Thenable { then(): void; }
declare let a: any;
declare let obj: { then: string; };
declare let thenable: Thenable;
async function fn1() { } // valid: Promise<void>
async function fn2(): { } { } // error
async function fn3(): any { } // error
async function fn4(): number { } // error
async function fn5(): PromiseLike<void> { } // error
async function fn6(): Thenable { } // error
async function fn7() { return; } // valid: Promise<void>
async function fn8() { return 1; } // valid: Promise<number>
async function fn9() { return null; } // valid: Promise<any>
async function fn10() { return undefined; } // valid: Promise<any>
async function fn11() { return a; } // valid: Promise<any>
async function fn12() { return obj; } // valid: Promise<{ then: string; }>
async function fn13() { return thenable; } // error
async function fn14() { await 1; } // valid: Promise<void>
async function fn15() { await null; } // valid: Promise<void>
async function fn16() { await undefined; } // valid: Promise<void>
async function fn17() { await a; } // valid: Promise<void>
async function fn18() { await obj; } // valid: Promise<void>
async function fn19() { await thenable; } // error

View File

@ -0,0 +1,5 @@
// @target: ES5
// @lib: es5,es2015.promise
// @noEmitHelpers: true
async function foo(): Promise<void> {
}

View File

@ -0,0 +1,5 @@
// @target: ES5
// @lib: es5,es2015.promise
// @noEmitHelpers: true
function f(await) {
}

View File

@ -0,0 +1,5 @@
// @target: ES5
// @lib: es5,es2015.promise
// @noEmitHelpers: true
function f(await = await) {
}

View File

@ -0,0 +1,5 @@
// @target: ES5
// @lib: es5,es2015.promise
// @noEmitHelpers: true
function await() {
}

View File

@ -0,0 +1,5 @@
// @target: ES5
// @lib: es5,es2015.promise
// @noEmitHelpers: true
async function foo(await): Promise<void> {
}

View File

@ -0,0 +1,5 @@
// @target: ES5
// @lib: es5,es2015.promise
// @noEmitHelpers: true
async function foo(a = await): Promise<void> {
}

View File

@ -0,0 +1,8 @@
// @target: ES5
// @lib: es5,es2015.promise
// @noEmitHelpers: true
async function bar(): Promise<void> {
// 'await' here is an identifier, and not a yield expression.
async function foo(a = await): Promise<void> {
}
}

View File

@ -0,0 +1,4 @@
// @target: ES5
// @lib: es5,es2015.promise
// @noEmitHelpers: true
var v = { [await]: foo }

View File

@ -0,0 +1,6 @@
// @target: ES5
// @lib: es5,es2015.promise
// @noEmitHelpers: true
async function foo(): Promise<void> {
var v = { [await]: foo }
}