From c0e4a1239a8715a237f618c1e988022efc60be71 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 18 Jul 2017 13:35:26 -0700 Subject: [PATCH 1/6] Fix many no-object-literal-type-assertion lint errors --- src/compiler/binder.ts | 27 +++--------- src/compiler/checker.ts | 14 +++---- src/compiler/core.ts | 8 ++++ src/compiler/emitter.ts | 2 +- src/compiler/factory.ts | 4 +- src/compiler/parser.ts | 2 +- src/compiler/transformers/generators.ts | 18 ++++---- src/harness/harness.ts | 2 +- src/harness/projectsRunner.ts | 4 +- src/harness/unittests/compileOnSave.ts | 12 +++--- .../convertCompilerOptionsFromJson.ts | 42 +++++++++---------- src/harness/unittests/matchFiles.ts | 20 ++++----- src/harness/unittests/session.ts | 4 +- src/harness/unittests/typingsInstaller.ts | 12 +++--- src/server/editorServices.ts | 12 +++--- src/server/session.ts | 8 ++-- .../typingsInstaller/typingsInstaller.ts | 4 +- 17 files changed, 92 insertions(+), 103 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index b07812d75ede9..b266f230525f0 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -801,11 +801,7 @@ namespace ts { return antecedent; } setFlowNodeReferenced(antecedent); - return { - flags, - expression, - antecedent - }; + return id({ flags, expression, antecedent }); } function createFlowSwitchClause(antecedent: FlowNode, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number): FlowNode { @@ -813,31 +809,18 @@ namespace ts { return antecedent; } setFlowNodeReferenced(antecedent); - return { - flags: FlowFlags.SwitchClause, - switchStatement, - clauseStart, - clauseEnd, - antecedent - }; + return id({ flags: FlowFlags.SwitchClause, switchStatement, clauseStart, clauseEnd, antecedent }); } function createFlowAssignment(antecedent: FlowNode, node: Expression | VariableDeclaration | BindingElement): FlowNode { setFlowNodeReferenced(antecedent); - return { - flags: FlowFlags.Assignment, - antecedent, - node - }; + return id({ flags: FlowFlags.Assignment, antecedent, node }); } function createFlowArrayMutation(antecedent: FlowNode, node: CallExpression | BinaryExpression): FlowNode { setFlowNodeReferenced(antecedent); - return { - flags: FlowFlags.ArrayMutation, - antecedent, - node - }; + const res: FlowArrayMutation = { flags: FlowFlags.ArrayMutation, antecedent, node }; + return res; } function finishFlowLabel(flow: FlowLabel): FlowNode { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 83f2fa179e4b8..09892b4a9fae9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2144,7 +2144,7 @@ namespace ts { if (accessibleSymbolChain) { const hasAccessibleDeclarations = hasVisibleDeclarations(accessibleSymbolChain[0], shouldComputeAliasesToMakeVisible); if (!hasAccessibleDeclarations) { - return { + return { accessibility: SymbolAccessibility.NotAccessible, errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning), errorModuleName: symbol !== initialSymbol ? symbolToString(symbol, enclosingDeclaration, SymbolFlags.Namespace) : undefined, @@ -2266,7 +2266,7 @@ namespace ts { const symbol = resolveName(enclosingDeclaration, (firstIdentifier).text, meaning, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined); // Verify if the symbol is accessible - return (symbol && hasVisibleDeclarations(symbol, /*shouldComputeAliasToMakeVisible*/ true)) || { + return (symbol && hasVisibleDeclarations(symbol, /*shouldComputeAliasToMakeVisible*/ true)) || { accessibility: SymbolAccessibility.NotAccessible, errorSymbolName: getTextOfNode(firstIdentifier), errorNode: firstIdentifier @@ -6254,16 +6254,16 @@ namespace ts { const parameterName = node.parameterName as Identifier; return { kind: TypePredicateKind.Identifier, - parameterName: parameterName ? parameterName.text : undefined, + parameterName: parameterName ? parameterName.text : undefined, parameterIndex: parameterName ? getTypePredicateParameterIndex((node.parent as SignatureDeclaration).parameters, parameterName) : undefined, type: getTypeFromTypeNode(node.type) - } as IdentifierTypePredicate; + }; } else { return { kind: TypePredicateKind.This, type: getTypeFromTypeNode(node.type) - } as ThisTypePredicate; + }; } } @@ -8015,13 +8015,13 @@ namespace ts { parameterName: predicate.parameterName, parameterIndex: predicate.parameterIndex, type: instantiateType(predicate.type, mapper) - } as IdentifierTypePredicate; + }; } else { return { kind: TypePredicateKind.This, type: instantiateType(predicate.type, mapper) - } as ThisTypePredicate; + }; } } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index cecf88f42cece..7f20051226342 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2543,4 +2543,12 @@ namespace ts { export function isCheckJsEnabledForFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) { return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs; } + + /** + * The identity function. + * Also useful to provide a contextual type for an object literal. + */ + export function id(value: T) { + return value; + } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 759fe9f0abc08..8a49504d17c5e 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1195,7 +1195,7 @@ namespace ts { if (!(getEmitFlags(node) & EmitFlags.NoIndentation)) { const dotRangeStart = node.expression.end; const dotRangeEnd = skipTrivia(currentSourceFile.text, node.expression.end) + 1; - const dotToken = { kind: SyntaxKind.DotToken, pos: dotRangeStart, end: dotRangeEnd }; + const dotToken = { kind: SyntaxKind.DotToken, pos: dotRangeStart, end: dotRangeEnd }; // tslint:disable-line no-object-literal-type-assertion indentBeforeDot = needsIndentation(node, node.expression, dotToken); indentAfterDot = needsIndentation(node, dotToken, node.name); } diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index e58f30a215f0b..316af4101742c 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -2586,7 +2586,7 @@ namespace ts { } export function addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean) { - return setSyntheticLeadingComments(node, append(getSyntheticLeadingComments(node), { kind, pos: -1, end: -1, hasTrailingNewLine, text })); + return setSyntheticLeadingComments(node, append(getSyntheticLeadingComments(node), { kind, pos: -1, end: -1, hasTrailingNewLine, text })); } export function getSyntheticTrailingComments(node: Node): SynthesizedComment[] | undefined { @@ -2600,7 +2600,7 @@ namespace ts { } export function addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean) { - return setSyntheticTrailingComments(node, append(getSyntheticTrailingComments(node), { kind, pos: -1, end: -1, hasTrailingNewLine, text })); + return setSyntheticTrailingComments(node, append(getSyntheticTrailingComments(node), { kind, pos: -1, end: -1, hasTrailingNewLine, text })); } /** diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 0be7734968fa9..d45c2980d0f4a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6118,7 +6118,7 @@ namespace ts { export function parseIsolatedJSDocComment(content: string, start: number, length: number) { initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS); - sourceFile = { languageVariant: LanguageVariant.Standard, text: content }; + sourceFile = { languageVariant: LanguageVariant.Standard, text: content }; // tslint:disable-line no-object-literal-type-assertion const jsDoc = parseJSDocCommentWorker(start, length); const diagnostics = parseDiagnostics; clearState(); diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index b120f5c8227a9..a9f241f0c8e89 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -2015,7 +2015,7 @@ namespace ts { * * @param block Information about the block. */ - function beginBlock(block: CodeBlock): number { + function beginBlock(block: T): number { if (!blocks) { blocks = []; blockActions = []; @@ -2070,7 +2070,7 @@ namespace ts { const startLabel = defineLabel(); const endLabel = defineLabel(); markLabel(startLabel); - beginBlock({ + beginBlock({ kind: CodeBlockKind.With, expression, startLabel, @@ -2098,7 +2098,7 @@ namespace ts { const startLabel = defineLabel(); const endLabel = defineLabel(); markLabel(startLabel); - beginBlock({ + beginBlock({ kind: CodeBlockKind.Exception, state: ExceptionBlockState.Try, startLabel, @@ -2199,7 +2199,7 @@ namespace ts { * @param labelText Names from containing labeled statements. */ function beginScriptLoopBlock(): void { - beginBlock({ + beginBlock({ kind: CodeBlockKind.Loop, isScript: true, breakLabel: -1, @@ -2217,7 +2217,7 @@ namespace ts { */ function beginLoopBlock(continueLabel: Label): Label { const breakLabel = defineLabel(); - beginBlock({ + beginBlock({ kind: CodeBlockKind.Loop, isScript: false, breakLabel, @@ -2245,7 +2245,7 @@ namespace ts { * */ function beginScriptSwitchBlock(): void { - beginBlock({ + beginBlock({ kind: CodeBlockKind.Switch, isScript: true, breakLabel: -1 @@ -2259,7 +2259,7 @@ namespace ts { */ function beginSwitchBlock(): Label { const breakLabel = defineLabel(); - beginBlock({ + beginBlock({ kind: CodeBlockKind.Switch, isScript: false, breakLabel, @@ -2280,7 +2280,7 @@ namespace ts { } function beginScriptLabeledBlock(labelText: string) { - beginBlock({ + beginBlock({ kind: CodeBlockKind.Labeled, isScript: true, labelText, @@ -2290,7 +2290,7 @@ namespace ts { function beginLabeledBlock(labelText: string) { const breakLabel = defineLabel(); - beginBlock({ + beginBlock({ kind: CodeBlockKind.Labeled, isScript: false, labelText, diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 55a8f3ebb4d71..e649584f10ba0 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -564,7 +564,7 @@ namespace Harness { } export let listFiles: typeof IO.listFiles = (path, spec?, options?) => { - options = options || <{ recursive?: boolean; }>{}; + options = options || {}; function filesInFolder(folder: string): string[] { let paths: string[] = []; diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index 7344c432b97ff..18cd8bee3ac51 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -426,12 +426,12 @@ class ProjectRunner extends RunnerBase { compilerResult.program ? ts.filter(compilerResult.program.getSourceFiles(), sourceFile => !Harness.isDefaultLibraryFile(sourceFile.fileName)) : []), - sourceFile => { + sourceFile => ts.id({ unitName: ts.isRootedDiskPath(sourceFile.fileName) ? RunnerBase.removeFullPaths(sourceFile.fileName) : sourceFile.fileName, content: sourceFile.text - }); + })); return Harness.Compiler.getErrorBaseline(inputFiles, compilerResult.errors); } diff --git a/src/harness/unittests/compileOnSave.ts b/src/harness/unittests/compileOnSave.ts index 79e1f921dcb82..897af56c1df0d 100644 --- a/src/harness/unittests/compileOnSave.ts +++ b/src/harness/unittests/compileOnSave.ts @@ -518,18 +518,18 @@ namespace ts.projectSystem { }; const host = createServerHost([f], { newLine }); const session = createSession(host); - session.executeCommand({ + session.executeCommand(id({ seq: 1, type: "request", - command: "open", + command: server.protocol.CommandTypes.Open, arguments: { file: f.path } - }); - session.executeCommand({ + })); + session.executeCommand(id({ seq: 2, type: "request", - command: "compileOnSaveEmitFile", + command: server.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: f.path } - }); + })); const emitOutput = host.readFile(path + ts.Extension.Js); assert.equal(emitOutput, f.content + newLine, "content of emit output should be identical with the input + newline"); } diff --git a/src/harness/unittests/convertCompilerOptionsFromJson.ts b/src/harness/unittests/convertCompilerOptionsFromJson.ts index 4b2fad32d7b55..14c0cb7347db3 100644 --- a/src/harness/unittests/convertCompilerOptionsFromJson.ts +++ b/src/harness/unittests/convertCompilerOptionsFromJson.ts @@ -67,14 +67,14 @@ namespace ts { } }, "tsconfig.json", { - compilerOptions: { + compilerOptions: { module: ModuleKind.CommonJS, target: ScriptTarget.ES5, noImplicitAny: false, sourceMap: false, lib: ["lib.es5.d.ts", "lib.es2015.core.d.ts", "lib.es2015.symbol.d.ts"] }, - errors: [] + errors: [] } ); }); @@ -92,7 +92,7 @@ namespace ts { } }, "tsconfig.json", { - compilerOptions: { + compilerOptions: { module: ModuleKind.CommonJS, target: ScriptTarget.ES5, noImplicitAny: false, @@ -100,7 +100,7 @@ namespace ts { allowJs: false, lib: ["lib.es5.d.ts", "lib.es2015.core.d.ts", "lib.es2015.symbol.d.ts"] }, - errors: [] + errors: [] } ); }); @@ -117,7 +117,7 @@ namespace ts { } }, "tsconfig.json", { - compilerOptions: { + compilerOptions: { module: ModuleKind.CommonJS, target: ScriptTarget.ES5, noImplicitAny: false, @@ -146,7 +146,7 @@ namespace ts { } }, "tsconfig.json", { - compilerOptions: { + compilerOptions: { target: ScriptTarget.ES5, noImplicitAny: false, sourceMap: false, @@ -174,7 +174,7 @@ namespace ts { } }, "tsconfig.json", { - compilerOptions: { + compilerOptions: { target: ScriptTarget.ES5, noImplicitAny: false, sourceMap: false, @@ -201,7 +201,7 @@ namespace ts { } }, "tsconfig.json", { - compilerOptions: { + compilerOptions: { noImplicitAny: false, sourceMap: false, }, @@ -227,7 +227,7 @@ namespace ts { } }, "tsconfig.json", { - compilerOptions: { + compilerOptions: { noImplicitAny: false, sourceMap: false, }, @@ -255,7 +255,7 @@ namespace ts { } }, "tsconfig.json", { - compilerOptions: { + compilerOptions: { module: ModuleKind.CommonJS, target: ScriptTarget.ES5, noImplicitAny: false, @@ -286,7 +286,7 @@ namespace ts { } }, "tsconfig.json", { - compilerOptions: { + compilerOptions: { module: ModuleKind.CommonJS, target: ScriptTarget.ES5, noImplicitAny: false, @@ -317,7 +317,7 @@ namespace ts { } }, "tsconfig.json", { - compilerOptions: { + compilerOptions: { module: ModuleKind.CommonJS, target: ScriptTarget.ES5, noImplicitAny: false, @@ -348,7 +348,7 @@ namespace ts { } }, "tsconfig.json", { - compilerOptions: { + compilerOptions: { module: ModuleKind.CommonJS, target: ScriptTarget.ES5, noImplicitAny: false, @@ -379,7 +379,7 @@ namespace ts { } }, "tsconfig.json", { - compilerOptions: { + compilerOptions: { module: ModuleKind.CommonJS, target: ScriptTarget.ES5, noImplicitAny: false, @@ -415,8 +415,8 @@ namespace ts { it("Convert default tsconfig.json to compiler-options ", () => { assertCompilerOptions({}, "tsconfig.json", { - compilerOptions: {} as CompilerOptions, - errors: [] + compilerOptions: {}, + errors: [] } ); }); @@ -434,7 +434,7 @@ namespace ts { } }, "jsconfig.json", { - compilerOptions: { + compilerOptions: { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, @@ -445,7 +445,7 @@ namespace ts { sourceMap: false, lib: ["lib.es5.d.ts", "lib.es2015.core.d.ts", "lib.es2015.symbol.d.ts"] }, - errors: [] + errors: [] } ); }); @@ -463,7 +463,7 @@ namespace ts { } }, "jsconfig.json", { - compilerOptions: { + compilerOptions: { allowJs: false, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, @@ -474,7 +474,7 @@ namespace ts { sourceMap: false, lib: ["lib.es5.d.ts", "lib.es2015.core.d.ts", "lib.es2015.symbol.d.ts"] }, - errors: [] + errors: [] } ); }); @@ -516,7 +516,7 @@ namespace ts { allowSyntheticDefaultImports: true, skipLibCheck: true }, - errors: [] + errors: [] } ); }); diff --git a/src/harness/unittests/matchFiles.ts b/src/harness/unittests/matchFiles.ts index e04546719302a..e14a0bfb42d3f 100644 --- a/src/harness/unittests/matchFiles.ts +++ b/src/harness/unittests/matchFiles.ts @@ -109,23 +109,21 @@ namespace ts { } { const actual = ts.parseJsonConfigFileContent(json, host, basePath, existingOptions, configFileName, resolutionStack); - expected.errors = map(expected.errors, error => { - return { - category: error.category, - code: error.code, - file: undefined, - length: undefined, - messageText: error.messageText, - start: undefined, - }; - }); + expected.errors = expected.errors.map(error => ({ + category: error.category, + code: error.code, + file: undefined, + length: undefined, + messageText: error.messageText, + start: undefined, + })); assertParsed(actual, expected); } } function createDiagnosticForConfigFile(json: any, start: number, length: number, diagnosticMessage: DiagnosticMessage, arg0: string) { const text = JSON.stringify(json); - const file = { + const file = { // tslint:disable-line no-object-literal-type-assertion fileName: caseInsensitiveTsconfigPath, kind: SyntaxKind.SourceFile, text diff --git a/src/harness/unittests/session.ts b/src/harness/unittests/session.ts index 862ebee4b03ab..081829dc5645e 100644 --- a/src/harness/unittests/session.ts +++ b/src/harness/unittests/session.ts @@ -93,14 +93,14 @@ namespace ts.server { session.executeCommand(req); - expect(lastSent).to.deep.equal({ + expect(lastSent).to.deep.equal(id({ command: CommandNames.Unknown, type: "response", seq: 0, message: "Unrecognized JSON command: foobar", request_seq: 0, success: false - }); + })); }); it("should return a tuple containing the response and if a response is required on success", () => { const req: protocol.ConfigureRequest = { diff --git a/src/harness/unittests/typingsInstaller.ts b/src/harness/unittests/typingsInstaller.ts index 5f6b1350578d8..c356d5f293c87 100644 --- a/src/harness/unittests/typingsInstaller.ts +++ b/src/harness/unittests/typingsInstaller.ts @@ -935,25 +935,25 @@ namespace ts.projectSystem { import * as cmd from "commander ` }; - session.executeCommand({ + session.executeCommand(id({ seq: 1, type: "request", - command: "open", + command: server.protocol.CommandTypes.Open, arguments: { file: f.path, fileContent: f.content } - }); + })); const projectService = session.getProjectService(); checkNumberOfProjects(projectService, { inferredProjects: 1 }); const proj = projectService.inferredProjects[0]; const version1 = proj.getCachedUnresolvedImportsPerFile_TestOnly().getVersion(); // make a change that should not affect the structure of the program - session.executeCommand({ + session.executeCommand(id({ seq: 2, type: "request", - command: "change", + command: server.protocol.CommandTypes.Change, arguments: { file: f.path, insertString: "\nlet x = 1;", @@ -962,7 +962,7 @@ namespace ts.projectSystem { endLine: 2, endOffset: 0 } - }); + })); host.checkTimeoutQueueLength(1); host.runQueuedTimeoutCallbacks(); const version2 = proj.getCachedUnresolvedImportsPerFile_TestOnly().getVersion(); diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 43cb429cfc5a6..186f243cdd132 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -444,10 +444,10 @@ namespace ts.server { if (!this.eventHandler) { return; } - this.eventHandler({ + this.eventHandler(id({ eventName: ProjectLanguageServiceStateEvent, data: { project, languageServiceEnabled } - }); + })); } updateTypingsForProject(response: SetTypings | InvalidateCachedTypings): void { @@ -605,10 +605,10 @@ namespace ts.server { } for (const openFile of this.openFiles) { - this.eventHandler({ + this.eventHandler(id({ eventName: ContextEvent, data: { project: openFile.getDefaultProject(), fileName: openFile.fileName } - }); + })); } } @@ -1110,10 +1110,10 @@ namespace ts.server { return; } - this.eventHandler({ + this.eventHandler(id({ eventName: ConfigFileDiagEvent, data: { configFileName, diagnostics: diagnostics || [], triggerFile } - }); + })); } private createAndAddConfiguredProject(configFileName: NormalizedPath, projectOptions: ProjectOptions, configFileErrors: Diagnostic[], clientFileName?: string) { diff --git a/src/server/session.ts b/src/server/session.ts index bd69640a4bbf3..f602cd95418a2 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -548,8 +548,8 @@ namespace ts.server { ); } - private convertToDiagnosticsWithLinePositionFromDiagnosticFile(diagnostics: Diagnostic[]) { - return diagnostics.map(d => { + private convertToDiagnosticsWithLinePositionFromDiagnosticFile(diagnostics: Diagnostic[]): protocol.DiagnosticWithLinePosition[] { + return diagnostics.map(d => ({ message: flattenDiagnosticMessageText(d.messageText, this.host.newLine), start: d.start, length: d.length, @@ -557,7 +557,7 @@ namespace ts.server { code: d.code, startLocation: d.file && convertToLocation(getLineAndCharacterOfPosition(d.file, d.start)), endLocation: d.file && convertToLocation(getLineAndCharacterOfPosition(d.file, d.start + d.length)) - }); + })); } private getCompilerOptionsDiagnostics(args: protocol.CompilerOptionsDiagnosticsRequestArgs) { @@ -836,7 +836,7 @@ namespace ts.server { return renameLocations.map(location => { const locationScriptInfo = project.getScriptInfo(location.fileName); - return { + return { file: location.fileName, start: locationScriptInfo.positionToLineOffset(location.textSpan.start), end: locationScriptInfo.positionToLineOffset(textSpanEnd(location.textSpan)), diff --git a/src/server/typingsInstaller/typingsInstaller.ts b/src/server/typingsInstaller/typingsInstaller.ts index b1fddfb412982..a7f4c7b84cfab 100644 --- a/src/server/typingsInstaller/typingsInstaller.ts +++ b/src/server/typingsInstaller/typingsInstaller.ts @@ -352,14 +352,14 @@ namespace ts.server.typingsInstaller { this.sendResponse(this.createSetTypings(req, currentlyCachedTypings.concat(installedTypingFiles))); } finally { - this.sendResponse({ + this.sendResponse(id({ kind: EventEndInstallTypes, eventId: requestId, projectName: req.projectName, packagesToInstall: scopedTypings, installSuccess: ok, typingsInstallerVersion: ts.version // qualified explicitly to prevent occasional shadowing - }); + })); } }); } From 08d8e04e431c01c202409d44a78365161b65b989 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 18 Jul 2017 14:59:07 -0700 Subject: [PATCH 2/6] Simple fixes --- src/compiler/checker.ts | 4 ++-- src/harness/projectsRunner.ts | 2 +- src/harness/unittests/matchFiles.ts | 2 +- src/harness/unittests/session.ts | 5 +++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 09892b4a9fae9..74faa831a7727 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6254,10 +6254,10 @@ namespace ts { const parameterName = node.parameterName as Identifier; return { kind: TypePredicateKind.Identifier, - parameterName: parameterName ? parameterName.text : undefined, + parameterName: parameterName ? parameterName.text : undefined, parameterIndex: parameterName ? getTypePredicateParameterIndex((node.parent as SignatureDeclaration).parameters, parameterName) : undefined, type: getTypeFromTypeNode(node.type) - }; + } as IdentifierTypePredicate; } else { return { diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index 18cd8bee3ac51..752767d970688 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -426,7 +426,7 @@ class ProjectRunner extends RunnerBase { compilerResult.program ? ts.filter(compilerResult.program.getSourceFiles(), sourceFile => !Harness.isDefaultLibraryFile(sourceFile.fileName)) : []), - sourceFile => ts.id({ + (sourceFile): Harness.Compiler.TestFile => ({ unitName: ts.isRootedDiskPath(sourceFile.fileName) ? RunnerBase.removeFullPaths(sourceFile.fileName) : sourceFile.fileName, diff --git a/src/harness/unittests/matchFiles.ts b/src/harness/unittests/matchFiles.ts index e14a0bfb42d3f..a8d123cf7e430 100644 --- a/src/harness/unittests/matchFiles.ts +++ b/src/harness/unittests/matchFiles.ts @@ -109,7 +109,7 @@ namespace ts { } { const actual = ts.parseJsonConfigFileContent(json, host, basePath, existingOptions, configFileName, resolutionStack); - expected.errors = expected.errors.map(error => ({ + expected.errors = expected.errors.map((error): Diagnostic => ({ category: error.category, code: error.code, file: undefined, diff --git a/src/harness/unittests/session.ts b/src/harness/unittests/session.ts index 081829dc5645e..449cc103d97ae 100644 --- a/src/harness/unittests/session.ts +++ b/src/harness/unittests/session.ts @@ -93,14 +93,15 @@ namespace ts.server { session.executeCommand(req); - expect(lastSent).to.deep.equal(id({ + const expected: protocol.Response = { command: CommandNames.Unknown, type: "response", seq: 0, message: "Unrecognized JSON command: foobar", request_seq: 0, success: false - })); + }; + expect(lastSent).to.deep.equal(expected); }); it("should return a tuple containing the response and if a response is required on success", () => { const req: protocol.ConfigureRequest = { From 7fcde0052d414a83a9f492ca12305148318e0afd Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 8 Aug 2017 11:16:13 -0700 Subject: [PATCH 3/6] Use a union for FlowNode --- src/compiler/binder.ts | 6 +++--- src/compiler/types.ts | 20 +++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index b266f230525f0..f7033fce1b4cb 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -801,7 +801,7 @@ namespace ts { return antecedent; } setFlowNodeReferenced(antecedent); - return id({ flags, expression, antecedent }); + return { flags, expression, antecedent }; } function createFlowSwitchClause(antecedent: FlowNode, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number): FlowNode { @@ -809,12 +809,12 @@ namespace ts { return antecedent; } setFlowNodeReferenced(antecedent); - return id({ flags: FlowFlags.SwitchClause, switchStatement, clauseStart, clauseEnd, antecedent }); + return { flags: FlowFlags.SwitchClause, switchStatement, clauseStart, clauseEnd, antecedent }; } function createFlowAssignment(antecedent: FlowNode, node: Expression | VariableDeclaration | BindingElement): FlowNode { setFlowNodeReferenced(antecedent); - return id({ flags: FlowFlags.Assignment, antecedent, node }); + return { flags: FlowFlags.Assignment, antecedent, node }; } function createFlowArrayMutation(antecedent: FlowNode, node: CallExpression | BinaryExpression): FlowNode { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f1f79e57d945b..f849b36d2decb 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2176,16 +2176,18 @@ namespace ts { locked?: boolean; } - export interface AfterFinallyFlow extends FlowNode, FlowLock { + export interface AfterFinallyFlow extends FlowNodeBase, FlowLock { antecedent: FlowNode; } - export interface PreFinallyFlow extends FlowNode { + export interface PreFinallyFlow extends FlowNodeBase { antecedent: FlowNode; lock: FlowLock; } - export interface FlowNode { + export type FlowNode = + | AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCondition | FlowSwitchClause | FlowArrayMutation; + export interface FlowNodeBase { flags: FlowFlags; id?: number; // Node id used by flow type cache in checker } @@ -2193,30 +2195,30 @@ namespace ts { // FlowStart represents the start of a control flow. For a function expression or arrow // function, the container property references the function (which in turn has a flowNode // property for the containing control flow). - export interface FlowStart extends FlowNode { + export interface FlowStart extends FlowNodeBase { container?: FunctionExpression | ArrowFunction | MethodDeclaration; } // FlowLabel represents a junction with multiple possible preceding control flows. - export interface FlowLabel extends FlowNode { + export interface FlowLabel extends FlowNodeBase { antecedents: FlowNode[]; } // FlowAssignment represents a node that assigns a value to a narrowable reference, // i.e. an identifier or a dotted name that starts with an identifier or 'this'. - export interface FlowAssignment extends FlowNode { + export interface FlowAssignment extends FlowNodeBase { node: Expression | VariableDeclaration | BindingElement; antecedent: FlowNode; } // FlowCondition represents a condition that is known to be true or false at the // node's location in the control flow. - export interface FlowCondition extends FlowNode { + export interface FlowCondition extends FlowNodeBase { expression: Expression; antecedent: FlowNode; } - export interface FlowSwitchClause extends FlowNode { + export interface FlowSwitchClause extends FlowNodeBase { switchStatement: SwitchStatement; clauseStart: number; // Start index of case/default clause range clauseEnd: number; // End index of case/default clause range @@ -2225,7 +2227,7 @@ namespace ts { // FlowArrayMutation represents a node potentially mutates an array, i.e. an // operation of the form 'x.push(value)', 'x.unshift(value)' or 'x[n] = value'. - export interface FlowArrayMutation extends FlowNode { + export interface FlowArrayMutation extends FlowNodeBase { node: CallExpression | BinaryExpression; antecedent: FlowNode; } From f6a2ea652ae0c151559489e86afae89662692939 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 8 Aug 2017 11:45:02 -0700 Subject: [PATCH 4/6] PR feedback and remove remaining `id()` uses --- src/compiler/core.ts | 8 -------- src/compiler/emitter.ts | 4 +++- src/harness/unittests/compileOnSave.ts | 10 ++++++---- src/harness/unittests/matchFiles.ts | 2 +- src/harness/unittests/typingsInstaller.ts | 10 ++++++---- src/server/editorServices.ts | 15 +++++++++------ src/server/session.ts | 4 ++-- src/server/typingsInstaller/typingsInstaller.ts | 5 +++-- 8 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index de30f595cbfce..d5c8396d06d6b 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2595,12 +2595,4 @@ namespace ts { export function isCheckJsEnabledForFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) { return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs; } - - /** - * The identity function. - * Also useful to provide a contextual type for an object literal. - */ - export function id(value: T) { - return value; - } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 9c3c9ac2845ee..42f4cc1495b20 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1195,7 +1195,9 @@ namespace ts { if (!(getEmitFlags(node) & EmitFlags.NoIndentation)) { const dotRangeStart = node.expression.end; const dotRangeEnd = skipTrivia(currentSourceFile.text, node.expression.end) + 1; - const dotToken = { kind: SyntaxKind.DotToken, pos: dotRangeStart, end: dotRangeEnd }; // tslint:disable-line no-object-literal-type-assertion + const dotToken = createToken(SyntaxKind.DotToken); + dotToken.pos = dotRangeStart; + dotToken.end = dotRangeEnd; indentBeforeDot = needsIndentation(node, node.expression, dotToken); indentAfterDot = needsIndentation(node, dotToken, node.name); } diff --git a/src/harness/unittests/compileOnSave.ts b/src/harness/unittests/compileOnSave.ts index 897af56c1df0d..31a882b19d69d 100644 --- a/src/harness/unittests/compileOnSave.ts +++ b/src/harness/unittests/compileOnSave.ts @@ -518,18 +518,20 @@ namespace ts.projectSystem { }; const host = createServerHost([f], { newLine }); const session = createSession(host); - session.executeCommand(id({ + const openRequest: server.protocol.OpenRequest = { seq: 1, type: "request", command: server.protocol.CommandTypes.Open, arguments: { file: f.path } - })); - session.executeCommand(id({ + }; + session.executeCommand(openRequest); + const emitFileRequest: server.protocol.CompileOnSaveEmitFileRequest = { seq: 2, type: "request", command: server.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: f.path } - })); + }; + session.executeCommand(emitFileRequest); const emitOutput = host.readFile(path + ts.Extension.Js); assert.equal(emitOutput, f.content + newLine, "content of emit output should be identical with the input + newline"); } diff --git a/src/harness/unittests/matchFiles.ts b/src/harness/unittests/matchFiles.ts index eb59dbf39b77f..f2c2369ef37f4 100644 --- a/src/harness/unittests/matchFiles.ts +++ b/src/harness/unittests/matchFiles.ts @@ -110,7 +110,7 @@ namespace ts { } { const actual = ts.parseJsonConfigFileContent(json, host, basePath, existingOptions, configFileName, resolutionStack); - expected.errors = expected.errors.map((error): Diagnostic => ({ + expected.errors = expected.errors.map(error => ({ category: error.category, code: error.code, file: undefined, diff --git a/src/harness/unittests/typingsInstaller.ts b/src/harness/unittests/typingsInstaller.ts index 1f9f1028e1b6e..5a26ab82da3bf 100644 --- a/src/harness/unittests/typingsInstaller.ts +++ b/src/harness/unittests/typingsInstaller.ts @@ -935,7 +935,7 @@ namespace ts.projectSystem { import * as cmd from "commander ` }; - session.executeCommand(id({ + const openRequest: server.protocol.OpenRequest = { seq: 1, type: "request", command: server.protocol.CommandTypes.Open, @@ -943,14 +943,15 @@ namespace ts.projectSystem { file: f.path, fileContent: f.content } - })); + }; + session.executeCommand(openRequest); const projectService = session.getProjectService(); checkNumberOfProjects(projectService, { inferredProjects: 1 }); const proj = projectService.inferredProjects[0]; const version1 = proj.getCachedUnresolvedImportsPerFile_TestOnly().getVersion(); // make a change that should not affect the structure of the program - session.executeCommand(id({ + const changeRequest: server.protocol.ChangeRequest = { seq: 2, type: "request", command: server.protocol.CommandTypes.Change, @@ -962,7 +963,8 @@ namespace ts.projectSystem { endLine: 2, endOffset: 0 } - })); + } + session.executeCommand(changeRequest); host.checkTimeoutQueueLength(1); host.runQueuedTimeoutCallbacks(); const version2 = proj.getCachedUnresolvedImportsPerFile_TestOnly().getVersion(); diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index e1183e9ad25d2..528ce487d3531 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -441,10 +441,11 @@ namespace ts.server { if (!this.eventHandler) { return; } - this.eventHandler(id({ + const event: ProjectLanguageServiceStateEvent = { eventName: ProjectLanguageServiceStateEvent, data: { project, languageServiceEnabled } - })); + }; + this.eventHandler(event); } updateTypingsForProject(response: SetTypings | InvalidateCachedTypings): void { @@ -602,10 +603,11 @@ namespace ts.server { } for (const openFile of this.openFiles) { - this.eventHandler(id({ + const event: ContextEvent = { eventName: ContextEvent, data: { project: openFile.getDefaultProject(), fileName: openFile.fileName } - })); + }; + this.eventHandler(event); } } @@ -1107,10 +1109,11 @@ namespace ts.server { return; } - this.eventHandler(id({ + const event: ConfigFileDiagEvent = { eventName: ConfigFileDiagEvent, data: { configFileName, diagnostics: diagnostics || [], triggerFile } - })); + }; + this.eventHandler(event); } private createAndAddConfiguredProject(configFileName: NormalizedPath, projectOptions: ProjectOptions, configFileErrors: Diagnostic[], clientFileName?: string) { diff --git a/src/server/session.ts b/src/server/session.ts index 14329845902c8..e1c6d37312fba 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -539,8 +539,8 @@ namespace ts.server { ); } - private convertToDiagnosticsWithLinePositionFromDiagnosticFile(diagnostics: Diagnostic[]): protocol.DiagnosticWithLinePosition[] { - return diagnostics.map(d => ({ + private convertToDiagnosticsWithLinePositionFromDiagnosticFile(diagnostics: Diagnostic[]) { + return diagnostics.map(d => ({ message: flattenDiagnosticMessageText(d.messageText, this.host.newLine), start: d.start, length: d.length, diff --git a/src/server/typingsInstaller/typingsInstaller.ts b/src/server/typingsInstaller/typingsInstaller.ts index eef150a9abe09..df2b6916e4bc0 100644 --- a/src/server/typingsInstaller/typingsInstaller.ts +++ b/src/server/typingsInstaller/typingsInstaller.ts @@ -356,14 +356,15 @@ namespace ts.server.typingsInstaller { this.sendResponse(this.createSetTypings(req, currentlyCachedTypings.concat(installedTypingFiles))); } finally { - this.sendResponse(id({ + const response: EndInstallTypes = { kind: EventEndInstallTypes, eventId: requestId, projectName: req.projectName, packagesToInstall: scopedTypings, installSuccess: ok, typingsInstallerVersion: ts.version // qualified explicitly to prevent occasional shadowing - })); + }; + this.sendResponse(response); } }); } From 78d5db6cb558c6e239b0d57acf758599386f2361 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 8 Aug 2017 12:37:21 -0700 Subject: [PATCH 5/6] Use a union for CodeBlock --- src/compiler/transformers/generators.ts | 31 ++++++++++++----------- src/harness/unittests/typingsInstaller.ts | 2 +- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 3bb57ff881691..f18b43e91bc7f 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -164,12 +164,13 @@ namespace ts { } // A generated code block - interface CodeBlock { + type CodeBlock = | ExceptionBlock | LabeledBlock | SwitchBlock | LoopBlock | WithBlock; + interface CodeBlockBase { kind: CodeBlockKind; } // a generated exception block, used for 'try' statements - interface ExceptionBlock extends CodeBlock { + interface ExceptionBlock extends CodeBlockBase { state: ExceptionBlockState; startLabel: Label; catchVariable?: Identifier; @@ -179,27 +180,27 @@ namespace ts { } // A generated code that tracks the target for 'break' statements in a LabeledStatement. - interface LabeledBlock extends CodeBlock { + interface LabeledBlock extends CodeBlockBase { labelText: string; isScript: boolean; breakLabel: Label; } // a generated block that tracks the target for 'break' statements in a 'switch' statement - interface SwitchBlock extends CodeBlock { + interface SwitchBlock extends CodeBlockBase { isScript: boolean; breakLabel: Label; } // a generated block that tracks the targets for 'break' and 'continue' statements, used for iteration statements - interface LoopBlock extends CodeBlock { + interface LoopBlock extends CodeBlockBase { continueLabel: Label; isScript: boolean; breakLabel: Label; } // a generated block associated with a 'with' statement - interface WithBlock extends CodeBlock { + interface WithBlock extends CodeBlockBase { expression: Identifier; startLabel: Label; endLabel: Label; @@ -2015,7 +2016,7 @@ namespace ts { * * @param block Information about the block. */ - function beginBlock(block: T): number { + function beginBlock(block: CodeBlock): number { if (!blocks) { blocks = []; blockActions = []; @@ -2070,7 +2071,7 @@ namespace ts { const startLabel = defineLabel(); const endLabel = defineLabel(); markLabel(startLabel); - beginBlock({ + beginBlock({ kind: CodeBlockKind.With, expression, startLabel, @@ -2098,7 +2099,7 @@ namespace ts { const startLabel = defineLabel(); const endLabel = defineLabel(); markLabel(startLabel); - beginBlock({ + beginBlock({ kind: CodeBlockKind.Exception, state: ExceptionBlockState.Try, startLabel, @@ -2199,7 +2200,7 @@ namespace ts { * @param labelText Names from containing labeled statements. */ function beginScriptLoopBlock(): void { - beginBlock({ + beginBlock({ kind: CodeBlockKind.Loop, isScript: true, breakLabel: -1, @@ -2217,7 +2218,7 @@ namespace ts { */ function beginLoopBlock(continueLabel: Label): Label { const breakLabel = defineLabel(); - beginBlock({ + beginBlock({ kind: CodeBlockKind.Loop, isScript: false, breakLabel, @@ -2245,7 +2246,7 @@ namespace ts { * */ function beginScriptSwitchBlock(): void { - beginBlock({ + beginBlock({ kind: CodeBlockKind.Switch, isScript: true, breakLabel: -1 @@ -2259,7 +2260,7 @@ namespace ts { */ function beginSwitchBlock(): Label { const breakLabel = defineLabel(); - beginBlock({ + beginBlock({ kind: CodeBlockKind.Switch, isScript: false, breakLabel, @@ -2280,7 +2281,7 @@ namespace ts { } function beginScriptLabeledBlock(labelText: string) { - beginBlock({ + beginBlock({ kind: CodeBlockKind.Labeled, isScript: true, labelText, @@ -2290,7 +2291,7 @@ namespace ts { function beginLabeledBlock(labelText: string) { const breakLabel = defineLabel(); - beginBlock({ + beginBlock({ kind: CodeBlockKind.Labeled, isScript: false, labelText, diff --git a/src/harness/unittests/typingsInstaller.ts b/src/harness/unittests/typingsInstaller.ts index 5a26ab82da3bf..6a6978254c12d 100644 --- a/src/harness/unittests/typingsInstaller.ts +++ b/src/harness/unittests/typingsInstaller.ts @@ -963,7 +963,7 @@ namespace ts.projectSystem { endLine: 2, endOffset: 0 } - } + }; session.executeCommand(changeRequest); host.checkTimeoutQueueLength(1); host.runQueuedTimeoutCallbacks(); From 4376d0f3c2c2cbf59b16edbba0392292f1ae8a18 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Wed, 9 Aug 2017 14:17:47 -0700 Subject: [PATCH 6/6] Discriminate CodeBlock by CodeBlockKind --- src/compiler/transformers/generators.ts | 77 ++++++++++++------------- 1 file changed, 37 insertions(+), 40 deletions(-) diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index f18b43e91bc7f..f45147b526c70 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -165,12 +165,10 @@ namespace ts { // A generated code block type CodeBlock = | ExceptionBlock | LabeledBlock | SwitchBlock | LoopBlock | WithBlock; - interface CodeBlockBase { - kind: CodeBlockKind; - } // a generated exception block, used for 'try' statements - interface ExceptionBlock extends CodeBlockBase { + interface ExceptionBlock { + kind: CodeBlockKind.Exception; state: ExceptionBlockState; startLabel: Label; catchVariable?: Identifier; @@ -180,27 +178,31 @@ namespace ts { } // A generated code that tracks the target for 'break' statements in a LabeledStatement. - interface LabeledBlock extends CodeBlockBase { + interface LabeledBlock { + kind: CodeBlockKind.Labeled; labelText: string; isScript: boolean; breakLabel: Label; } // a generated block that tracks the target for 'break' statements in a 'switch' statement - interface SwitchBlock extends CodeBlockBase { + interface SwitchBlock { + kind: CodeBlockKind.Switch; isScript: boolean; breakLabel: Label; } // a generated block that tracks the targets for 'break' and 'continue' statements, used for iteration statements - interface LoopBlock extends CodeBlockBase { + interface LoopBlock { + kind: CodeBlockKind.Loop; continueLabel: Label; isScript: boolean; breakLabel: Label; } // a generated block associated with a 'with' statement - interface WithBlock extends CodeBlockBase { + interface WithBlock { + kind: CodeBlockKind.With; expression: Identifier; startLabel: Label; endLabel: Label; @@ -2088,10 +2090,6 @@ namespace ts { markLabel(block.endLabel); } - function isWithBlock(block: CodeBlock): block is WithBlock { - return block.kind === CodeBlockKind.With; - } - /** * Begins a code block for a generated `try` statement. */ @@ -2189,10 +2187,6 @@ namespace ts { exception.state = ExceptionBlockState.Done; } - function isExceptionBlock(block: CodeBlock): block is ExceptionBlock { - return block.kind === CodeBlockKind.Exception; - } - /** * Begins a code block that supports `break` or `continue` statements that are defined in * the source tree and not from generated code. @@ -2879,34 +2873,37 @@ namespace ts { for (; blockIndex < blockActions.length && blockOffsets[blockIndex] <= operationIndex; blockIndex++) { const block = blocks[blockIndex]; const blockAction = blockActions[blockIndex]; - if (isExceptionBlock(block)) { - if (blockAction === BlockAction.Open) { - if (!exceptionBlockStack) { - exceptionBlockStack = []; - } + switch (block.kind) { + case CodeBlockKind.Exception: + if (blockAction === BlockAction.Open) { + if (!exceptionBlockStack) { + exceptionBlockStack = []; + } - if (!statements) { - statements = []; - } + if (!statements) { + statements = []; + } - exceptionBlockStack.push(currentExceptionBlock); - currentExceptionBlock = block; - } - else if (blockAction === BlockAction.Close) { - currentExceptionBlock = exceptionBlockStack.pop(); - } - } - else if (isWithBlock(block)) { - if (blockAction === BlockAction.Open) { - if (!withBlockStack) { - withBlockStack = []; + exceptionBlockStack.push(currentExceptionBlock); + currentExceptionBlock = block; } + else if (blockAction === BlockAction.Close) { + currentExceptionBlock = exceptionBlockStack.pop(); + } + break; + case CodeBlockKind.With: + if (blockAction === BlockAction.Open) { + if (!withBlockStack) { + withBlockStack = []; + } - withBlockStack.push(block); - } - else if (blockAction === BlockAction.Close) { - withBlockStack.pop(); - } + withBlockStack.push(block); + } + else if (blockAction === BlockAction.Close) { + withBlockStack.pop(); + } + break; + // default: do nothing } } }