Fix emit for type as expression

This commit is contained in:
Ron Buckton 2015-12-01 12:12:31 -08:00
parent c792fd2d8e
commit 88a43ccb4a
3 changed files with 30 additions and 41 deletions

View File

@ -9884,15 +9884,15 @@ namespace ts {
const hasExplicitReturn = func.flags & NodeFlags.HasExplicitReturn;
if (returnType && !hasExplicitReturn) {
// minimal check: function has syntactic return type annotation and no explicit return statements in the body
// minimal check: function has syntactic return type annotation and no explicit return statements in the body
// this function does not conform to the specification.
// NOTE: having returnType !== undefined is a precondition for entering this branch so func.type will always be present
// NOTE: having returnType !== undefined is a precondition for entering this branch so func.type will always be present
error(func.type, Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value);
}
else if (compilerOptions.noImplicitReturns) {
if (!returnType) {
// If return type annotation is omitted check if function has any explicit return statements.
// If it does not have any - its inferred return type is void - don't do any checks.
// If it does not have any - its inferred return type is void - don't do any checks.
// Otherwise get inferred return type from function body and report error only if it is not void / anytype
const inferredReturnType = hasExplicitReturn
? getReturnTypeOfSignature(getSignatureFromDeclaration(func))
@ -11922,13 +11922,8 @@ namespace ts {
return unknownType;
}
// If the constructor, resolved locally, is an alias symbol we should mark it as referenced.
const promiseName = getEntityNameFromTypeNode(node.type);
const promiseNameOrNamespaceRoot = getFirstIdentifier(promiseName);
const promiseAliasSymbol = resolveName(node, promiseNameOrNamespaceRoot.text, SymbolFlags.Alias, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined);
if (promiseAliasSymbol) {
markAliasSymbolAsReferenced(promiseAliasSymbol);
}
// If the Promise constructor, resolved locally, is an alias symbol we should mark it as referenced.
checkReturnTypeAnnotationAsExpression(node);
// Validate the promise constructor type.
const promiseConstructorType = getTypeOfSymbol(promiseConstructor);
@ -11937,6 +11932,8 @@ namespace ts {
}
// Verify there is no local declaration that could collide with the promise constructor.
const promiseName = getEntityNameFromTypeNode(node.type);
const promiseNameOrNamespaceRoot = getFirstIdentifier(promiseName);
const rootSymbol = getSymbol(node.locals, promiseNameOrNamespaceRoot.text, SymbolFlags.Value);
if (rootSymbol) {
error(rootSymbol.valueDeclaration, Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions,
@ -12024,24 +12021,12 @@ namespace ts {
* Checks the type annotation of an accessor declaration or property declaration as
* an expression if it is a type reference to a type with a value declaration.
*/
function checkTypeAnnotationAsExpression(node: AccessorDeclaration | PropertyDeclaration | ParameterDeclaration | MethodDeclaration) {
switch (node.kind) {
case SyntaxKind.PropertyDeclaration:
checkTypeNodeAsExpression((<PropertyDeclaration>node).type);
break;
case SyntaxKind.Parameter:
checkTypeNodeAsExpression((<ParameterDeclaration>node).type);
break;
case SyntaxKind.MethodDeclaration:
checkTypeNodeAsExpression((<MethodDeclaration>node).type);
break;
case SyntaxKind.GetAccessor:
checkTypeNodeAsExpression((<AccessorDeclaration>node).type);
break;
case SyntaxKind.SetAccessor:
checkTypeNodeAsExpression(getSetAccessorTypeAnnotationNode(<AccessorDeclaration>node));
break;
}
function checkTypeAnnotationAsExpression(node: VariableLikeDeclaration) {
checkTypeNodeAsExpression((<PropertyDeclaration>node).type);
}
function checkReturnTypeAnnotationAsExpression(node: FunctionLikeDeclaration) {
checkTypeNodeAsExpression(node.type);
}
/** Checks the type annotation of the parameters of a function/method or the constructor of a class as expressions */
@ -12079,11 +12064,12 @@ namespace ts {
break;
case SyntaxKind.MethodDeclaration:
checkParameterTypeAnnotationsAsExpressions(<FunctionLikeDeclaration>node);
// fall-through
case SyntaxKind.SetAccessor:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
checkParameterTypeAnnotationsAsExpressions(<FunctionLikeDeclaration>node);
checkReturnTypeAnnotationAsExpression(<FunctionLikeDeclaration>node);
break;
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.Parameter:
checkTypeAnnotationAsExpression(<PropertyDeclaration | ParameterDeclaration>node);

View File

@ -2190,7 +2190,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
emit(node.right);
}
function emitEntityNameAsExpression(node: EntityName, useFallback: boolean) {
function emitEntityNameAsExpression(node: EntityName | Expression, useFallback: boolean) {
switch (node.kind) {
case SyntaxKind.Identifier:
if (useFallback) {
@ -2205,6 +2205,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
case SyntaxKind.QualifiedName:
emitQualifiedNameAsExpression(<QualifiedName>node, useFallback);
break;
default:
emitNodeWithoutSourceMap(node);
break;
}
}
@ -2980,7 +2984,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
else {
// this is top level converted loop so we need to create an alias for 'this' here
// NOTE:
// NOTE:
// if converted loops were all nested in arrow function then we'll always emit '_this' so convertedLoopState.thisName will not be set.
// If it is set this means that all nested loops are not nested in arrow function and it is safe to capture 'this'.
write(`var ${convertedLoopState.thisName} = this;`);
@ -4457,18 +4461,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write(" __awaiter(this");
if (hasLexicalArguments) {
write(", arguments");
write(", arguments, ");
}
else {
write(", void 0");
write(", void 0, ");
}
if (promiseConstructor) {
write(", ");
emitNodeWithoutSourceMap(promiseConstructor);
emitEntityNameAsExpression(promiseConstructor, /*useFallback*/ false);
}
else {
write(", Promise");
write("Promise");
}
// Emit the call to __awaiter.
@ -5744,7 +5747,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
/** Serializes the return type of function. Used by the __metadata decorator for a method. */
function emitSerializedReturnTypeOfNode(node: Node): string | string[] {
function emitSerializedReturnTypeOfNode(node: Node) {
if (node && isFunctionLike(node) && (<FunctionLikeDeclaration>node).type) {
emitSerializedTypeNode((<FunctionLikeDeclaration>node).type);
return;

View File

@ -32,6 +32,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
var task_1 = require("./task");
class Test {
example() {
return __awaiter(this, void 0, Task, function* () { return; });
return __awaiter(this, void 0, task_1.Task, function* () { return; });
}
}