Fix unreachable code detection persisting after incremental edits (#62783)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
This commit is contained in:
Copilot 2025-11-19 09:46:30 -08:00 committed by GitHub
parent cc2610fd34
commit 486fce7a12
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 72 additions and 0 deletions

View File

@ -1091,6 +1091,11 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
// and set it before we descend into nodes that could actually be part of an assignment pattern.
inAssignmentPattern = false;
// Clear Unreachable flag from previous binding (for incremental scenarios)
if (isPotentiallyExecutableNode(node)) {
(node as Mutable<Node>).flags &= ~NodeFlags.Unreachable;
}
if (currentFlow === unreachableFlow) {
if (canHaveFlowNode(node)) {
node.flowNode = undefined;

View File

@ -0,0 +1,44 @@
/// <reference path="fourslash.ts" />
// @allowUnreachableCode: false
// @lib: es2015
// @Filename: /base/browser/browser.ts
//// export const isStandalone = true;
// @Filename: /base/browser/dom.ts
//// export function addDisposableListener() {}
// @Filename: /base/browser/window.ts
//// export const mainWindow = {} as Window;
// @Filename: /workbench.ts
//// /*before*/import { isStandalone } from './base/browser/browser';
//// import { addDisposableListener } from './base/browser/dom';
//// import { mainWindow } from './base/browser/window';
////
//// interface ISecretStorageCrypto {
//// seal(data: string): Promise<string>;
//// unseal(data: string): Promise<string>;
//// }
////
//// export class TransparentCrypto implements ISecretStorageCrypto {
//// async seal(data: string): Promise<string> {
//// return data;
//// }
//// async unseal(data: string): Promise<string> {
//// return data;
//// }
//// }
verify.numberOfErrorsInCurrentFile(0);
goTo.marker("before");
edit.insert("throw new Error('foo');\n");
verify.numberOfErrorsInCurrentFile(1);
goTo.marker("before");
edit.deleteAtCaret("throw new Error('foo');\n".length);
verify.numberOfErrorsInCurrentFile(0);

View File

@ -0,0 +1,23 @@
/// <reference path="fourslash.ts" />
// @allowUnusedLabels: false
//// myLabel: while (true) {
//// if (Math.random() > 0.5) {
//// /*marker*/break myLabel;
//// }
//// }
verify.numberOfErrorsInCurrentFile(0);
goTo.marker("marker");
edit.deleteAtCaret("break myLabel;".length);
edit.insert("break;");
verify.numberOfErrorsInCurrentFile(1);
goTo.marker("marker");
edit.deleteAtCaret("break;".length);
edit.insert("break myLabel;");
verify.numberOfErrorsInCurrentFile(0);