From 4f681a2d8fb2d2d2d5d969eb9cf6c5e0f434cb32 Mon Sep 17 00:00:00 2001 From: Dimitri Benin Date: Wed, 20 Mar 2019 00:54:54 +0100 Subject: [PATCH 1/3] Walk node tree to collect data about `expectError` statements --- source/lib/compiler.ts | 22 +++++++++++-------- .../expect-error/values/index.test-d.ts | 8 +++++++ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/source/lib/compiler.ts b/source/lib/compiler.ts index 204326b3..5229d278 100644 --- a/source/lib/compiler.ts +++ b/source/lib/compiler.ts @@ -1,5 +1,7 @@ import * as path from 'path'; -import {flattenDiagnosticMessageText, createProgram, SyntaxKind, Diagnostic as TSDiagnostic, Program, SourceFile} from 'typescript'; +import { + flattenDiagnosticMessageText, createProgram, SyntaxKind, Diagnostic as TSDiagnostic, + Program, SourceFile, Node, forEachChild} from 'typescript'; import {Diagnostic, DiagnosticCode, Context, Location} from './interfaces'; // List of diagnostic codes that should be ignored @@ -22,18 +24,18 @@ const extractExpectErrorRanges = (program: Program) => { const expectedErrors = new Map>(); for (const sourceFile of program.getSourceFiles()) { - for (const statement of sourceFile.statements) { - if (statement.kind !== SyntaxKind.ExpressionStatement || !statement.getText().startsWith('expectError')) { - continue; - } + walkNodes(sourceFile); + } + function walkNodes(node: Node) { + if (node.kind === SyntaxKind.ExpressionStatement && node.getText().startsWith('expectError')) { const location = { - fileName: statement.getSourceFile().fileName, - start: statement.getStart(), - end: statement.getEnd() + fileName: node.getSourceFile().fileName, + start: node.getStart(), + end: node.getEnd() }; - const pos = statement.getSourceFile().getLineAndCharacterOfPosition(statement.getStart()); + const pos = node.getSourceFile().getLineAndCharacterOfPosition(node.getStart()); expectedErrors.set(location, { fileName: location.fileName, @@ -41,6 +43,8 @@ const extractExpectErrorRanges = (program: Program) => { column: pos.character }); } + + forEachChild(node, walkNodes); } return expectedErrors; diff --git a/source/test/fixtures/expect-error/values/index.test-d.ts b/source/test/fixtures/expect-error/values/index.test-d.ts index 941661fe..50babdbc 100644 --- a/source/test/fixtures/expect-error/values/index.test-d.ts +++ b/source/test/fixtures/expect-error/values/index.test-d.ts @@ -9,3 +9,11 @@ const foo: {readonly bar: string} = { expectError(foo.bar = 'quux'); expectError(foo.quux); + +// Ignore errors in deeply nested blocks, too +try { + if (true) { + expectError(foo.bar = 'quux'); + expectError(foo.quux); + } +} catch (e) {} From 6d4e55414a9f923a3c2d5282052ced6259fc3dc6 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 20 Mar 2019 14:10:43 +0700 Subject: [PATCH 2/3] Update index.test-d.ts --- source/test/fixtures/expect-error/values/index.test-d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/test/fixtures/expect-error/values/index.test-d.ts b/source/test/fixtures/expect-error/values/index.test-d.ts index 50babdbc..052c69e5 100644 --- a/source/test/fixtures/expect-error/values/index.test-d.ts +++ b/source/test/fixtures/expect-error/values/index.test-d.ts @@ -10,10 +10,10 @@ const foo: {readonly bar: string} = { expectError(foo.bar = 'quux'); expectError(foo.quux); -// Ignore errors in deeply nested blocks, too +// Ignore errors in deeply nested blocks too try { if (true) { expectError(foo.bar = 'quux'); expectError(foo.quux); } -} catch (e) {} +} catch {} From c22e0fa4fa6217ca16df7492b5b91abce346af47 Mon Sep 17 00:00:00 2001 From: Dimitri Benin Date: Wed, 20 Mar 2019 10:30:46 +0100 Subject: [PATCH 3/3] Fixes after review --- source/lib/compiler.ts | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/source/lib/compiler.ts b/source/lib/compiler.ts index 5229d278..1b515c8d 100644 --- a/source/lib/compiler.ts +++ b/source/lib/compiler.ts @@ -1,7 +1,14 @@ import * as path from 'path'; import { - flattenDiagnosticMessageText, createProgram, SyntaxKind, Diagnostic as TSDiagnostic, - Program, SourceFile, Node, forEachChild} from 'typescript'; + flattenDiagnosticMessageText, + createProgram, + SyntaxKind, + Diagnostic as TSDiagnostic, + Program, + SourceFile, + Node, + forEachChild +} from 'typescript'; import {Diagnostic, DiagnosticCode, Context, Location} from './interfaces'; // List of diagnostic codes that should be ignored @@ -23,10 +30,6 @@ const diagnosticCodesToIgnore = new Set([ const extractExpectErrorRanges = (program: Program) => { const expectedErrors = new Map>(); - for (const sourceFile of program.getSourceFiles()) { - walkNodes(sourceFile); - } - function walkNodes(node: Node) { if (node.kind === SyntaxKind.ExpressionStatement && node.getText().startsWith('expectError')) { const location = { @@ -35,7 +38,9 @@ const extractExpectErrorRanges = (program: Program) => { end: node.getEnd() }; - const pos = node.getSourceFile().getLineAndCharacterOfPosition(node.getStart()); + const pos = node + .getSourceFile() + .getLineAndCharacterOfPosition(node.getStart()); expectedErrors.set(location, { fileName: location.fileName, @@ -47,6 +52,10 @@ const extractExpectErrorRanges = (program: Program) => { forEachChild(node, walkNodes); } + for (const sourceFile of program.getSourceFiles()) { + walkNodes(sourceFile); + } + return expectedErrors; };