Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions src/traceDiagnosticFilter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import * as ts from 'typescript'

const declarationFilePattern = /\.d\.(?:cts|mts|ts)$/i

export function shouldSuppressTraceDiagnostic(fileName: string, sourceText: string, position: number): boolean {
return createTraceDiagnosticFilter(fileName, sourceText)(position)
}

export function createTraceDiagnosticFilter(fileName: string, sourceText: string) {
if (declarationFilePattern.test(fileName))
return () => true

const sourceFile = ts.createSourceFile(fileName, sourceText, ts.ScriptTarget.Latest, true)
return (position: number) => {
const node = findNodeAtPosition(sourceFile, position)

for (let current = node; current; current = current.parent) {
if (ts.isTypeAliasDeclaration(current) || ts.isInterfaceDeclaration(current))
return true
}

return false
}
}

function findNodeAtPosition(node: ts.Node, position: number): ts.Node | undefined {
if (position < node.getStart() || position >= node.getEnd())
return undefined

const child = ts.forEachChild(node, current => findNodeAtPosition(current, position))
return child ?? node
}
6 changes: 6 additions & 0 deletions src/traceDiagnostics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as vscode from 'vscode'
import type { FileStat } from '../shared/src/messages'
import { getStatsFromTree } from './traceTree'
import { afterConfigUpdate, getCurrentConfig } from './configuration'
import { createTraceDiagnosticFilter } from './traceDiagnosticFilter'

let diagnosticCollection: vscode.DiagnosticCollection

Expand Down Expand Up @@ -49,6 +50,8 @@ export async function addTraceDiagnostics(fileName: string, stats: FileStat[]) {
fileStatus.set(fileName, 'clean')

const document = await vscode.workspace.openTextDocument(uri)
const sourceText = document.getText()
const shouldSuppressTraceDiagnostic = createTraceDiagnosticFilter(document.fileName, sourceText)

let averages

Expand All @@ -72,6 +75,9 @@ export async function addTraceDiagnostics(fileName: string, stats: FileStat[]) {
if (lastPos === stat.pos)
continue // do not create diagnostics for further checks at the same starting position

if (shouldSuppressTraceDiagnostic(stat.pos))
continue

const diagnostic = toDiagnistic(stat, document, averages!)
if (diagnostic)
diagnostics.push(diagnostic)
Expand Down
32 changes: 32 additions & 0 deletions test/trace-diagnostic-filter.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { describe, expect, it } from 'vitest'
import { shouldSuppressTraceDiagnostic } from '../src/traceDiagnosticFilter'

describe('shouldSuppressTraceDiagnostic', () => {
it('suppresses declaration files', () => {
expect(shouldSuppressTraceDiagnostic('node_modules/typescript/lib/lib.es2020.date.d.ts', 'declare const Date: DateConstructor', 10)).toBe(true)
})

it('suppresses type alias diagnostics anywhere in the declaration', () => {
const source = `export type ConstructorOf<Instance extends object> = new (
...args: any[]
) => Instance`

expect(shouldSuppressTraceDiagnostic('src/example.ts', source, source.indexOf('any[]'))).toBe(true)
})

it('suppresses interface diagnostics', () => {
const source = `export interface Person {
name: string
}`

expect(shouldSuppressTraceDiagnostic('src/example.ts', source, source.indexOf('string'))).toBe(true)
})

it('keeps value-level diagnostics', () => {
const source = `export const person: Person = {
name: 'Ada',
}`

expect(shouldSuppressTraceDiagnostic('src/example.ts', source, source.indexOf('Person'))).toBe(false)
})
})