diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cdb0babd587..3d2c64c7ced 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6024,7 +6024,7 @@ module ts { function getReturnTypeFromBody(func: FunctionLikeDeclaration, contextualMapper?: TypeMapper): Type { var contextualSignature = getContextualSignatureForFunctionLikeDeclaration(func); - if (func.body.kind !== SyntaxKind.FunctionBlock) { + if (func.body.kind !== SyntaxKind.Block) { var unwidenedType = checkAndMarkExpression(func.body, contextualMapper); var widenedType = getWidenedType(unwidenedType); @@ -6111,7 +6111,7 @@ module ts { } // If all we have is a function signature, or an arrow function with an expression body, then there is nothing to check. - if (!func.body || func.body.kind !== SyntaxKind.FunctionBlock) { + if (!func.body || func.body.kind !== SyntaxKind.Block) { return; } @@ -6177,7 +6177,7 @@ module ts { if (node.type) { checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNode(node.type)); } - if (node.body.kind === SyntaxKind.FunctionBlock) { + if (node.body.kind === SyntaxKind.Block) { checkSourceElement(node.body); } else { @@ -7360,6 +7360,9 @@ module ts { function checkBlock(node: Block) { forEach(node.statements, checkSourceElement); + if (isFunctionBlock(node) || node.kind === SyntaxKind.ModuleBlock) { + checkFunctionExpressionBodies(node); + } } function checkCollisionWithArgumentsInGeneratedCode(node: SignatureDeclaration) { @@ -8491,10 +8494,8 @@ module ts { case SyntaxKind.FunctionDeclaration: return checkFunctionDeclaration(node); case SyntaxKind.Block: - return checkBlock(node); - case SyntaxKind.FunctionBlock: case SyntaxKind.ModuleBlock: - return checkBody(node); + return checkBlock(node); case SyntaxKind.VariableStatement: return checkVariableStatement(node); case SyntaxKind.ExpressionStatement: @@ -8589,7 +8590,6 @@ module ts { case SyntaxKind.BinaryExpression: case SyntaxKind.ConditionalExpression: case SyntaxKind.Block: - case SyntaxKind.FunctionBlock: case SyntaxKind.ModuleBlock: case SyntaxKind.VariableStatement: case SyntaxKind.ExpressionStatement: @@ -8620,11 +8620,6 @@ module ts { } } - function checkBody(node: Block) { - checkBlock(node); - checkFunctionExpressionBodies(node); - } - // Fully type check a source file and collect the relevant diagnostics. function checkSourceFile(node: SourceFile) { var links = getNodeLinks(node); diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 38cd18aea07..08589c36923 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2841,17 +2841,17 @@ module ts { scopeEmitStart(node); increaseIndent(); - emitDetachedComments(node.body.kind === SyntaxKind.FunctionBlock ? (node.body).statements : node.body); + emitDetachedComments(node.body.kind === SyntaxKind.Block ? (node.body).statements : node.body); var startIndex = 0; - if (node.body.kind === SyntaxKind.FunctionBlock) { + if (node.body.kind === SyntaxKind.Block) { startIndex = emitDirectivePrologues((node.body).statements, /*startWithNewLine*/ true); } var outPos = writer.getTextPos(); emitCaptureThisForNodeIfNecessary(node); emitDefaultValueAssignments(node); emitRestParameter(node); - if (node.body.kind !== SyntaxKind.FunctionBlock && outPos === writer.getTextPos()) { + if (node.body.kind !== SyntaxKind.Block && outPos === writer.getTextPos()) { decreaseIndent(); write(" "); emitStart(node.body); @@ -2864,7 +2864,7 @@ module ts { emitEnd(node.body); } else { - if (node.body.kind === SyntaxKind.FunctionBlock) { + if (node.body.kind === SyntaxKind.Block) { emitLinesStartingAt((node.body).statements, startIndex); } else { @@ -2876,7 +2876,7 @@ module ts { emitTrailingComments(node.body); } writeLine(); - if (node.body.kind === SyntaxKind.FunctionBlock) { + if (node.body.kind === SyntaxKind.Block) { emitLeadingCommentsOfPosition((node.body).statements.end); decreaseIndent(); emitToken(SyntaxKind.CloseBraceToken, (node.body).statements.end); @@ -3566,7 +3566,7 @@ module ts { case SyntaxKind.Block: case SyntaxKind.TryBlock: case SyntaxKind.FinallyBlock: - case SyntaxKind.FunctionBlock: + case SyntaxKind.Block: case SyntaxKind.ModuleBlock: return emitBlock(node); case SyntaxKind.VariableStatement: diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 615f472aaa5..5414794f429 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -311,7 +311,6 @@ module ts { case SyntaxKind.Block: case SyntaxKind.TryBlock: case SyntaxKind.FinallyBlock: - case SyntaxKind.FunctionBlock: case SyntaxKind.ModuleBlock: return children((node).statements); case SyntaxKind.SourceFile: @@ -435,7 +434,6 @@ module ts { case SyntaxKind.ReturnStatement: return visitor(node); case SyntaxKind.Block: - case SyntaxKind.FunctionBlock: case SyntaxKind.IfStatement: case SyntaxKind.DoStatement: case SyntaxKind.WhileStatement: @@ -472,6 +470,10 @@ module ts { return false; } + export function isFunctionBlock(node: Node) { + return node && node.kind === SyntaxKind.Block && isAnyFunction(node.parent); + } + export function getContainingFunction(node: Node): FunctionLikeDeclaration { while (true) { node = node.parent; @@ -3287,7 +3289,7 @@ module ts { var savedYieldContext = inYieldContext(); setYieldContext(allowYield); - var block = parseBlock(SyntaxKind.FunctionBlock, ignoreMissingOpenBrace, /*checkForStrictMode*/ true); + var block = parseBlock(SyntaxKind.Block, ignoreMissingOpenBrace, /*checkForStrictMode*/ true); setYieldContext(savedYieldContext); @@ -4360,7 +4362,7 @@ module ts { if (!checkModifiers(node)) { var savedInFunctionBlock = inFunctionBlock; - if (node.kind === SyntaxKind.FunctionBlock) { + if (isFunctionBlock(node)) { inFunctionBlock = true; } @@ -4996,7 +4998,7 @@ module ts { } function checkForBodyInAmbientContext(body: Block | Expression, isConstructor: boolean): boolean { - if (inAmbientContext && body && body.kind === SyntaxKind.FunctionBlock) { + if (inAmbientContext && body && body.kind === SyntaxKind.Block) { var diagnostic = isConstructor ? Diagnostics.A_constructor_implementation_cannot_be_declared_in_an_ambient_context : Diagnostics.A_function_implementation_cannot_be_declared_in_an_ambient_context; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index aa8a98db902..eadbb483319 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -212,7 +212,6 @@ module ts { DebuggerStatement, VariableDeclaration, FunctionDeclaration, - FunctionBlock, ClassDeclaration, InterfaceDeclaration, TypeAliasDeclaration, diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index d70884e5d87..4b7b276086f 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -101,10 +101,14 @@ module ts.BreakpointResolver { case SyntaxKind.ArrowFunction: return spanInFunctionDeclaration(node); - case SyntaxKind.FunctionBlock: - return spanInFunctionBlock(node); - case SyntaxKind.Block: + if (isFunctionBlock(node)) { + return spanInFunctionBlock(node); + } + else { + return spanInBlock(node); + } + case SyntaxKind.TryBlock: case SyntaxKind.FinallyBlock: case SyntaxKind.ModuleBlock: @@ -414,13 +418,18 @@ module ts.BreakpointResolver { return undefined; } - case SyntaxKind.FunctionBlock: case SyntaxKind.EnumDeclaration: case SyntaxKind.ClassDeclaration: // Span on close brace token return textSpan(node); case SyntaxKind.Block: + if (isFunctionBlock(node.parent)) { + // Span on close brace token + return textSpan(node); + } + // fall through. + case SyntaxKind.TryBlock: case SyntaxKind.CatchClause: case SyntaxKind.FinallyBlock: diff --git a/src/services/formatting.ts b/src/services/formatting.ts index 3322ea1e65b..9660d9af6df 100644 --- a/src/services/formatting.ts +++ b/src/services/formatting.ts @@ -897,7 +897,7 @@ module ts.formatting { function isSomeBlock(kind: SyntaxKind): boolean { switch (kind) { case SyntaxKind.Block: - case SyntaxKind.FunctionBlock: + case SyntaxKind.Block: case SyntaxKind.TryBlock: case SyntaxKind.FinallyBlock: case SyntaxKind.ModuleBlock: diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 2723b50af7b..5dc44650346 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -526,7 +526,6 @@ module ts.formatting { case SyntaxKind.ObjectLiteralExpression: case SyntaxKind.TryBlock: case SyntaxKind.FinallyBlock: - case SyntaxKind.FunctionBlock: case SyntaxKind.ModuleBlock: return true; } @@ -582,7 +581,6 @@ module ts.formatting { case SyntaxKind.TryBlock: case SyntaxKind.CatchClause: case SyntaxKind.FinallyBlock: - case SyntaxKind.FunctionBlock: case SyntaxKind.ModuleBlock: case SyntaxKind.SwitchStatement: return true; diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index deb779bea2c..aebd736d190 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -120,7 +120,7 @@ module ts.NavigationBar { if (functionDeclaration.kind === SyntaxKind.FunctionDeclaration) { // A function declaration is 'top level' if it contains any function declarations // within it. - if (functionDeclaration.body && functionDeclaration.body.kind === SyntaxKind.FunctionBlock) { + if (functionDeclaration.body && functionDeclaration.body.kind === SyntaxKind.Block) { // Proper function declarations can only have identifier names if (forEach((functionDeclaration.body).statements, s => s.kind === SyntaxKind.FunctionDeclaration && !isEmpty((s).name.text))) { @@ -130,7 +130,7 @@ module ts.NavigationBar { // Or if it is not parented by another function. i.e all functions // at module scope are 'top level'. - if (functionDeclaration.parent.kind !== SyntaxKind.FunctionBlock) { + if (!isFunctionBlock(functionDeclaration.parent)) { return true; } } @@ -333,7 +333,7 @@ module ts.NavigationBar { } function createFunctionItem(node: FunctionDeclaration) { - if (node.name && node.body && node.body.kind === SyntaxKind.FunctionBlock) { + if (node.name && node.body && node.body.kind === SyntaxKind.Block) { var childItems = getItemsWorker(sortNodes((node.body).statements), createChildItem); return getNavigationBarItem(node.name.text, diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts index 68f30bee781..83eef2f4378 100644 --- a/src/services/outliningElementsCollector.ts +++ b/src/services/outliningElementsCollector.ts @@ -67,38 +67,39 @@ module ts { } switch (n.kind) { case SyntaxKind.Block: - var parent = n.parent; - var openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile); - var closeBrace = findChildOfKind(n, SyntaxKind.CloseBraceToken, sourceFile); + if (!isFunctionBlock(n)) { + var parent = n.parent; + var openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile); + var closeBrace = findChildOfKind(n, SyntaxKind.CloseBraceToken, sourceFile); - // Check if the block is standalone, or 'attached' to some parent statement. - // If the latter, we want to collaps the block, but consider its hint span - // to be the entire span of the parent. - if (parent.kind === SyntaxKind.DoStatement || - parent.kind === SyntaxKind.ForInStatement || - parent.kind === SyntaxKind.ForStatement || - parent.kind === SyntaxKind.IfStatement || - parent.kind === SyntaxKind.WhileStatement || - parent.kind === SyntaxKind.WithStatement || - parent.kind === SyntaxKind.CatchClause) { - - addOutliningSpan(parent, openBrace, closeBrace, autoCollapse(n)); + // Check if the block is standalone, or 'attached' to some parent statement. + // If the latter, we want to collaps the block, but consider its hint span + // to be the entire span of the parent. + if (parent.kind === SyntaxKind.DoStatement || + parent.kind === SyntaxKind.ForInStatement || + parent.kind === SyntaxKind.ForStatement || + parent.kind === SyntaxKind.IfStatement || + parent.kind === SyntaxKind.WhileStatement || + parent.kind === SyntaxKind.WithStatement || + parent.kind === SyntaxKind.CatchClause) { + + addOutliningSpan(parent, openBrace, closeBrace, autoCollapse(n)); + } + else { + // Block was a standalone block. In this case we want to only collapse + // the span of the block, independent of any parent span. + var span = TextSpan.fromBounds(n.getStart(), n.end); + elements.push({ + textSpan: span, + hintSpan: span, + bannerText: collapseText, + autoCollapse: autoCollapse(n) + }); + } + break; } - else { - // Block was a standalone block. In this case we want to only collapse - // the span of the block, independent of any parent span. - var span = TextSpan.fromBounds(n.getStart(), n.end); - elements.push({ - textSpan: span, - hintSpan: span, - bannerText: collapseText, - autoCollapse: autoCollapse(n) - }); - } - break; + // Fallthrough. - - case SyntaxKind.FunctionBlock: case SyntaxKind.ModuleBlock: case SyntaxKind.TryBlock: case SyntaxKind.FinallyBlock: diff --git a/src/services/services.ts b/src/services/services.ts index a04c85071e2..15cc6639669 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -806,10 +806,15 @@ module ts { case SyntaxKind.Constructor: case SyntaxKind.VariableStatement: case SyntaxKind.ModuleBlock: - case SyntaxKind.FunctionBlock: forEachChild(node, visit); break; + case SyntaxKind.Block: + if (isFunctionBlock(node)) { + forEachChild(node, visit); + } + break; + case SyntaxKind.Parameter: // Only consider properties defined as constructor parameters if (!(node.flags & NodeFlags.AccessibilityModifier)) { @@ -1441,7 +1446,7 @@ module ts { } // If the parent is not sourceFile or module block it is local variable - for (var parent = declaration.parent; parent.kind !== SyntaxKind.FunctionBlock; parent = parent.parent) { + for (var parent = declaration.parent; !isFunctionBlock(parent); parent = parent.parent) { // Reached source file or module block if (parent.kind === SyntaxKind.SourceFile || parent.kind === SyntaxKind.ModuleBlock) { return false; @@ -3515,7 +3520,7 @@ module ts { var func = getContainingFunction(returnStatement); // If we didn't find a containing function with a block body, bail out. - if (!(func && hasKind(func.body, SyntaxKind.FunctionBlock))) { + if (!(func && hasKind(func.body, SyntaxKind.Block))) { return undefined; } @@ -3547,7 +3552,7 @@ module ts { // If the "owner" is a function, then we equate 'return' and 'throw' statements in their // ability to "jump out" of the function, and include occurrences for both. - if (owner.kind === SyntaxKind.FunctionBlock) { + if (isFunctionBlock(owner)) { forEachReturnStatement(owner, returnStatement => { pushKeywordIf(keywords, returnStatement.getFirstToken(), SyntaxKind.ReturnKeyword); }); @@ -3603,7 +3608,7 @@ module ts { while (child.parent) { var parent = child.parent; - if (parent.kind === SyntaxKind.FunctionBlock || parent.kind === SyntaxKind.SourceFile) { + if (isFunctionBlock(parent) || parent.kind === SyntaxKind.SourceFile) { return parent; } diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 93363b4676b..bdb76b77e8a 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -396,7 +396,7 @@ module ts.SignatureHelp { function getContainingArgumentInfo(node: Node): ArgumentListInfo { for (var n = node; n.kind !== SyntaxKind.SourceFile; n = n.parent) { - if (n.kind === SyntaxKind.FunctionBlock) { + if (isFunctionBlock(n)) { return undefined; } diff --git a/src/services/smartIndenter.ts b/src/services/smartIndenter.ts index 82226449b96..e93cb5616a9 100644 --- a/src/services/smartIndenter.ts +++ b/src/services/smartIndenter.ts @@ -326,7 +326,6 @@ module ts.formatting { case SyntaxKind.EnumDeclaration: case SyntaxKind.ArrayLiteralExpression: case SyntaxKind.Block: - case SyntaxKind.FunctionBlock: case SyntaxKind.TryBlock: case SyntaxKind.FinallyBlock: case SyntaxKind.ModuleBlock: @@ -357,7 +356,6 @@ module ts.formatting { case SyntaxKind.ForInStatement: case SyntaxKind.ForStatement: case SyntaxKind.IfStatement: - return child !== SyntaxKind.Block; case SyntaxKind.FunctionDeclaration: case SyntaxKind.FunctionExpression: case SyntaxKind.Method: @@ -365,7 +363,7 @@ module ts.formatting { case SyntaxKind.Constructor: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: - return child !== SyntaxKind.FunctionBlock; + return child !== SyntaxKind.Block; default: return false; } @@ -404,7 +402,6 @@ module ts.formatting { case SyntaxKind.ObjectLiteralExpression: case SyntaxKind.Block: case SyntaxKind.FinallyBlock: - case SyntaxKind.FunctionBlock: case SyntaxKind.ModuleBlock: case SyntaxKind.SwitchStatement: return nodeEndsWith(n, SyntaxKind.CloseBraceToken, sourceFile);