Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c792fd2

Browse filesBrowse files
committed
Merge branch 'master' into fixAsyncReferecedImport
2 parents c108042 + b40079e commit c792fd2
Copy full SHA for c792fd2

18 files changed

+801-327Lines changed: 801 additions & 327 deletions
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/compiler/checker.ts‎

Copy file name to clipboardExpand all lines: src/compiler/checker.ts
+24-15Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9871,31 +9871,39 @@ namespace ts {
98719871
}
98729872

98739873
// Functions with with an explicitly specified 'void' or 'any' return type don't need any return expressions.
9874-
if (returnType && (returnType === voidType || isTypeAny(returnType))) {
9875-
return;
9876-
}
9877-
9878-
// if return type is not specified then we'll do the check only if 'noImplicitReturns' option is set
9879-
if (!returnType && !compilerOptions.noImplicitReturns) {
9874+
if (returnType === voidType || isTypeAny(returnType)) {
98809875
return;
98819876
}
98829877

98839878
// If all we have is a function signature, or an arrow function with an expression body, then there is nothing to check.
9884-
// also if HasImplicitReturnValue flags is not set this means that all codepaths in function body end with return of throw
9879+
// also if HasImplicitReturn flag is not set this means that all codepaths in function body end with return or throw
98859880
if (nodeIsMissing(func.body) || func.body.kind !== SyntaxKind.Block || !(func.flags & NodeFlags.HasImplicitReturn)) {
98869881
return;
98879882
}
98889883

9889-
if (!returnType || func.flags & NodeFlags.HasExplicitReturn) {
9890-
if (compilerOptions.noImplicitReturns) {
9891-
error(func.type || func, Diagnostics.Not_all_code_paths_return_a_value);
9892-
}
9893-
}
9894-
else {
9895-
// This function does not conform to the specification.
9896-
// NOTE: having returnType !== undefined is a precondition for entering this branch so func.type will always be present
9884+
const hasExplicitReturn = func.flags & NodeFlags.HasExplicitReturn;
9885+
9886+
if (returnType && !hasExplicitReturn) {
9887+
// minimal check: function has syntactic return type annotation and no explicit return statements in the body
9888+
// this function does not conform to the specification.
9889+
// NOTE: having returnType !== undefined is a precondition for entering this branch so func.type will always be present
98979890
error(func.type, Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value);
98989891
}
9892+
else if (compilerOptions.noImplicitReturns) {
9893+
if (!returnType) {
9894+
// If return type annotation is omitted check if function has any explicit return statements.
9895+
// If it does not have any - its inferred return type is void - don't do any checks.
9896+
// Otherwise get inferred return type from function body and report error only if it is not void / anytype
9897+
const inferredReturnType = hasExplicitReturn
9898+
? getReturnTypeOfSignature(getSignatureFromDeclaration(func))
9899+
: voidType;
9900+
9901+
if (inferredReturnType === voidType || isTypeAny(inferredReturnType)) {
9902+
return;
9903+
}
9904+
}
9905+
error(func.type || func, Diagnostics.Not_all_code_paths_return_a_value);
9906+
}
98999907
}
99009908

99019909
function checkFunctionExpressionOrObjectLiteralMethod(node: FunctionExpression | MethodDeclaration, contextualMapper?: TypeMapper): Type {
@@ -14376,6 +14384,7 @@ namespace ts {
1437614384
emitExtends = false;
1437714385
emitDecorate = false;
1437814386
emitParam = false;
14387+
emitAwaiter = false;
1437914388
potentialThisCollisions.length = 0;
1438014389

1438114390
forEach(node.statements, checkSourceElement);
Collapse file

‎src/compiler/emitter.ts‎

Copy file name to clipboardExpand all lines: src/compiler/emitter.ts
+26-30Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5307,10 +5307,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
53075307
function emitDecoratorsOfConstructor(node: ClassLikeDeclaration) {
53085308
const decorators = node.decorators;
53095309
const constructor = getFirstConstructorWithBody(node);
5310-
const hasDecoratedParameters = constructor && forEach(constructor.parameters, nodeIsDecorated);
5310+
const firstParameterDecorator = constructor && forEach(constructor.parameters, parameter => parameter.decorators);
53115311

53125312
// skip decoration of the constructor if neither it nor its parameters are decorated
5313-
if (!decorators && !hasDecoratedParameters) {
5313+
if (!decorators && !firstParameterDecorator) {
53145314
return;
53155315
}
53165316

@@ -5326,28 +5326,27 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
53265326
//
53275327

53285328
writeLine();
5329-
emitStart(node);
5329+
emitStart(node.decorators || firstParameterDecorator);
53305330
emitDeclarationName(node);
53315331
write(" = __decorate([");
53325332
increaseIndent();
53335333
writeLine();
53345334

53355335
const decoratorCount = decorators ? decorators.length : 0;
5336-
let argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true, decorator => {
5337-
emitStart(decorator);
5338-
emit(decorator.expression);
5339-
emitEnd(decorator);
5340-
});
5341-
5342-
argumentsWritten += emitDecoratorsOfParameters(constructor, /*leadingComma*/ argumentsWritten > 0);
5336+
let argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true,
5337+
decorator => emit(decorator.expression));
5338+
if (firstParameterDecorator) {
5339+
argumentsWritten += emitDecoratorsOfParameters(constructor, /*leadingComma*/ argumentsWritten > 0);
5340+
}
53435341
emitSerializedTypeMetadata(node, /*leadingComma*/ argumentsWritten >= 0);
53445342

53455343
decreaseIndent();
53465344
writeLine();
53475345
write("], ");
53485346
emitDeclarationName(node);
5349-
write(");");
5350-
emitEnd(node);
5347+
write(")");
5348+
emitEnd(node.decorators || firstParameterDecorator);
5349+
write(";");
53515350
writeLine();
53525351
}
53535352

@@ -5363,11 +5362,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
53635362
continue;
53645363
}
53655364

5366-
// skip a member if it or any of its parameters are not decorated
5367-
if (!nodeOrChildIsDecorated(member)) {
5368-
continue;
5369-
}
5370-
53715365
// skip an accessor declaration if it is not the first accessor
53725366
let decorators: NodeArray<Decorator>;
53735367
let functionLikeMember: FunctionLikeDeclaration;
@@ -5394,6 +5388,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
53945388
functionLikeMember = <MethodDeclaration>member;
53955389
}
53965390
}
5391+
const firstParameterDecorator = functionLikeMember && forEach(functionLikeMember.parameters, parameter => parameter.decorators);
5392+
5393+
// skip a member if it or any of its parameters are not decorated
5394+
if (!decorators && !firstParameterDecorator) {
5395+
continue;
5396+
}
53975397

53985398
// Emit the call to __decorate. Given the following:
53995399
//
@@ -5427,29 +5427,26 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
54275427
//
54285428

54295429
writeLine();
5430-
emitStart(member);
5430+
emitStart(decorators || firstParameterDecorator);
54315431
write("__decorate([");
54325432
increaseIndent();
54335433
writeLine();
54345434

54355435
const decoratorCount = decorators ? decorators.length : 0;
5436-
let argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true, decorator => {
5437-
emitStart(decorator);
5438-
emit(decorator.expression);
5439-
emitEnd(decorator);
5440-
});
5436+
let argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true,
5437+
decorator => emit(decorator.expression));
54415438

5442-
argumentsWritten += emitDecoratorsOfParameters(functionLikeMember, argumentsWritten > 0);
5439+
if (firstParameterDecorator) {
5440+
argumentsWritten += emitDecoratorsOfParameters(functionLikeMember, argumentsWritten > 0);
5441+
}
54435442
emitSerializedTypeMetadata(member, argumentsWritten > 0);
54445443

54455444
decreaseIndent();
54465445
writeLine();
54475446
write("], ");
5448-
emitStart(member.name);
54495447
emitClassMemberPrefix(node, member);
54505448
write(", ");
54515449
emitExpressionForPropertyName(member.name);
5452-
emitEnd(member.name);
54535450

54545451
if (languageVersion > ScriptTarget.ES3) {
54555452
if (member.kind !== SyntaxKind.PropertyDeclaration) {
@@ -5464,8 +5461,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
54645461
}
54655462
}
54665463

5467-
write(");");
5468-
emitEnd(member);
5464+
write(")");
5465+
emitEnd(decorators || firstParameterDecorator);
5466+
write(";");
54695467
writeLine();
54705468
}
54715469
}
@@ -5478,11 +5476,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
54785476
if (nodeIsDecorated(parameter)) {
54795477
const decorators = parameter.decorators;
54805478
argumentsWritten += emitList(decorators, 0, decorators.length, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ leadingComma, /*noTrailingNewLine*/ true, decorator => {
5481-
emitStart(decorator);
54825479
write(`__param(${parameterIndex}, `);
54835480
emit(decorator.expression);
54845481
write(")");
5485-
emitEnd(decorator);
54865482
});
54875483
leadingComma = true;
54885484
}
Collapse file

‎src/compiler/parser.ts‎

Copy file name to clipboardExpand all lines: src/compiler/parser.ts
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4902,7 +4902,7 @@ namespace ts {
49024902

49034903
if (!decorators) {
49044904
decorators = <NodeArray<Decorator>>[];
4905-
decorators.pos = scanner.getStartPos();
4905+
decorators.pos = decoratorStart;
49064906
}
49074907

49084908
const decorator = <Decorator>createNode(SyntaxKind.Decorator, decoratorStart);
Collapse file

‎src/compiler/sourcemap.ts‎

Copy file name to clipboardExpand all lines: src/compiler/sourcemap.ts
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,8 @@ namespace ts {
251251
}
252252

253253
function emitStart(range: TextRange) {
254-
emitPos(range.pos !== -1 ? skipTrivia(currentSourceFile.text, range.pos) : -1);
254+
const rangeHasDecorators = !!(range as Node).decorators;
255+
emitPos(range.pos !== -1 ? skipTrivia(currentSourceFile.text, rangeHasDecorators ? (range as Node).decorators.end : range.pos) : -1);
255256
}
256257

257258
function emitEnd(range: TextRange) {
Collapse file

‎src/compiler/utilities.ts‎

Copy file name to clipboardExpand all lines: src/compiler/utilities.ts
-17Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -906,23 +906,6 @@ namespace ts {
906906
return false;
907907
}
908908

909-
export function childIsDecorated(node: Node): boolean {
910-
switch (node.kind) {
911-
case SyntaxKind.ClassDeclaration:
912-
return forEach((<ClassDeclaration>node).members, nodeOrChildIsDecorated);
913-
914-
case SyntaxKind.MethodDeclaration:
915-
case SyntaxKind.SetAccessor:
916-
return forEach((<FunctionLikeDeclaration>node).parameters, nodeIsDecorated);
917-
}
918-
919-
return false;
920-
}
921-
922-
export function nodeOrChildIsDecorated(node: Node): boolean {
923-
return nodeIsDecorated(node) || childIsDecorated(node);
924-
}
925-
926909
export function isPropertyAccessExpression(node: Node): node is PropertyAccessExpression {
927910
return node.kind === SyntaxKind.PropertyAccessExpression;
928911
}
Collapse file

‎src/services/breakpoints.ts‎

Copy file name to clipboardExpand all lines: src/services/breakpoints.ts
+18-3Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace ts.BreakpointResolver {
1616

1717
let tokenAtLocation = getTokenAtPosition(sourceFile, position);
1818
let lineOfPosition = sourceFile.getLineAndCharacterOfPosition(position).line;
19-
if (sourceFile.getLineAndCharacterOfPosition(tokenAtLocation.getStart()).line > lineOfPosition) {
19+
if (sourceFile.getLineAndCharacterOfPosition(tokenAtLocation.getStart(sourceFile)).line > lineOfPosition) {
2020
// Get previous token if the token is returned starts on new line
2121
// eg: let x =10; |--- cursor is here
2222
// let y = 10;
@@ -39,16 +39,23 @@ namespace ts.BreakpointResolver {
3939
return spanInNode(tokenAtLocation);
4040

4141
function textSpan(startNode: Node, endNode?: Node) {
42-
return createTextSpanFromBounds(startNode.getStart(), (endNode || startNode).getEnd());
42+
const start = startNode.decorators ?
43+
skipTrivia(sourceFile.text, startNode.decorators.end) :
44+
startNode.getStart(sourceFile);
45+
return createTextSpanFromBounds(start, (endNode || startNode).getEnd());
4346
}
4447

4548
function spanInNodeIfStartsOnSameLine(node: Node, otherwiseOnNode?: Node): TextSpan {
46-
if (node && lineOfPosition === sourceFile.getLineAndCharacterOfPosition(node.getStart()).line) {
49+
if (node && lineOfPosition === sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line) {
4750
return spanInNode(node);
4851
}
4952
return spanInNode(otherwiseOnNode);
5053
}
5154

55+
function spanInNodeArray<T>(nodeArray: NodeArray<T>) {
56+
return createTextSpanFromBounds(skipTrivia(sourceFile.text, nodeArray.pos), nodeArray.end);
57+
}
58+
5259
function spanInPreviousNode(node: Node): TextSpan {
5360
return spanInNode(findPrecedingToken(node.pos, sourceFile));
5461
}
@@ -65,6 +72,11 @@ namespace ts.BreakpointResolver {
6572
return spanInPreviousNode(node);
6673
}
6774

75+
if (node.parent.kind === SyntaxKind.Decorator) {
76+
// Set breakpoint on the decorator emit
77+
return spanInNode(node.parent);
78+
}
79+
6880
if (node.parent.kind === SyntaxKind.ForStatement) {
6981
// For now lets set the span on this expression, fix it later
7082
return textSpan(node);
@@ -207,6 +219,9 @@ namespace ts.BreakpointResolver {
207219
// span in statement
208220
return spanInNode((<WithStatement>node).statement);
209221

222+
case SyntaxKind.Decorator:
223+
return spanInNodeArray(node.parent.decorators);
224+
210225
// No breakpoint in interface, type alias
211226
case SyntaxKind.InterfaceDeclaration:
212227
case SyntaxKind.TypeAliasDeclaration:
Collapse file
+26Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//// [tests/cases/conformance/async/es6/asyncMultiFile.ts] ////
2+
3+
//// [a.ts]
4+
async function f() {}
5+
//// [b.ts]
6+
function g() { }
7+
8+
//// [a.js]
9+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) {
10+
return new Promise(function (resolve, reject) {
11+
generator = generator.call(thisArg, _arguments);
12+
function cast(value) { return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve) { resolve(value); }); }
13+
function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } }
14+
function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } }
15+
function step(verb, value) {
16+
var result = generator[verb](value);
17+
result.done ? resolve(result.value) : cast(result.value).then(onfulfill, onreject);
18+
}
19+
step("next", void 0);
20+
});
21+
};
22+
function f() {
23+
return __awaiter(this, void 0, Promise, function* () { });
24+
}
25+
//// [b.js]
26+
function g() { }
Collapse file
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
=== tests/cases/conformance/async/es6/a.ts ===
2+
async function f() {}
3+
>f : Symbol(f, Decl(a.ts, 0, 0))
4+
5+
=== tests/cases/conformance/async/es6/b.ts ===
6+
function g() { }
7+
>g : Symbol(g, Decl(b.ts, 0, 0))
8+
Collapse file
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
=== tests/cases/conformance/async/es6/a.ts ===
2+
async function f() {}
3+
>f : () => Promise<void>
4+
5+
=== tests/cases/conformance/async/es6/b.ts ===
6+
function g() { }
7+
>g : () => void
8+

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.