Skip to content

Commit

Permalink
fix!: rework highlight node (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu authored Jan 17, 2024
1 parent d4a8ce5 commit 390a92c
Show file tree
Hide file tree
Showing 11 changed files with 31 additions and 56 deletions.
2 changes: 1 addition & 1 deletion packages/twoslash-vue/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export function createTwoslasher(createOptions: CreateTwoslashVueOptions = {}):
removals: [] as Range[],
positionCompletions: [] as number[],
positionQueries: [] as number[],
positionHighlights: [] as Range[],
positionHighlights: [] as TwoslashReturnMeta['positionHighlights'],
flagNotations: [] as ParsedFlagNotation[],
} satisfies Partial<TwoslashReturnMeta>

Expand Down
37 changes: 7 additions & 30 deletions packages/twoslash/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { CompilerOptions, CompletionEntry, CompletionTriggerKind, JsxEmit }
import { createFSBackedSystem, createSystem, createVirtualTypeScriptEnvironment } from '@typescript/vfs'
import { TwoslashError } from './error'
import type { CompilerOptionDeclaration, CreateTwoslashOptions, NodeError, NodeWithoutPosition, Position, Range, TwoslashExecuteOptions, TwoslashInstance, TwoslashOptions, TwoslashReturn, TwoslashReturnMeta, VirtualFile } from './types'
import { areRangesIntersecting, createPositionConverter, findCutNotations, findFlagNotations, findQueryMarkers, getExtension, getIdentifierTextSpans, getObjectHash, isInRange, isInRanges, removeCodeRanges, removeTsExtension, resolveNodePositions, splitFiles, typesToExtension } from './utils'
import { createPositionConverter, findCutNotations, findFlagNotations, findQueryMarkers, getExtension, getIdentifierTextSpans, getObjectHash, isInRange, isInRanges, removeCodeRanges, removeTsExtension, resolveNodePositions, splitFiles, typesToExtension } from './utils'
import { validateCodeForErrors } from './validation'
import { defaultCompilerOptions, defaultHandbookOptions } from './defaults'

Expand Down Expand Up @@ -239,35 +239,12 @@ export function createTwoslasher(createOptions: CreateTwoslashOptions = {}): Two

// #region get highlights
for (const highlight of meta.positionHighlights) {
if (isInRemoval(highlight[0])) {
throw new TwoslashError(
`Invalid highlight query`,
`The request on line ${pc.indexToPos(highlight[0]).line + 2} for highlight via ^^^ is in a removal range.`,
`This is likely that the positioning is off.`,
)
}

const file = getFileAtPosition(highlight[0])!
const identifiers = getIdentifiersOfFile(file)

const ids = identifiers.filter(i => areRangesIntersecting(i as unknown as Range, highlight))
const matched = ids
.map(i => getQuickInfo(file, i[0], i[2]))
.filter(Boolean) as NodeWithoutPosition[]
if (matched.length) {
for (const node of matched) {
node.type = 'highlight'
nodes.push(node)
}
}
else {
const pos = pc.indexToPos(highlight[0])
throw new TwoslashError(
`Invalid highlight query`,
`The request on line ${pos.line + 2} in ${file.filename} for highlight via ^^^ is returned nothing from the compiler.`,
`This is likely that the positioning is off.`,
)
}
nodes.push({
type: 'highlight',
start: highlight[0],
length: highlight[1] - highlight[0],
text: highlight[2],
})
}
// #endregion

Expand Down
7 changes: 4 additions & 3 deletions packages/twoslash/src/legacy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,12 @@ export function convertLegacyReturn(result: TwoslashReturn): TwoslashReturnLegac
highlights: result.highlights
.map((h): TwoslashReturnLegacy['highlights'][0] => ({
kind: 'highlight',
offset: h.character,
start: h.start,
// it's a bit confusing that `offset` and `start` are flipped
offset: h.start,
start: h.character,
length: h.length,
line: h.line,
text: h.text,
text: h.text || '',
})),

queries: ([
Expand Down
4 changes: 3 additions & 1 deletion packages/twoslash/src/types/nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ export interface NodeHover extends NodeBase {
tags?: [name: string, text: string | undefined][]
}

export interface NodeHighlight extends Omit<NodeHover, 'type'> {
export interface NodeHighlight extends NodeBase {
type: 'highlight'
/** The annotation message */
text?: string
}

export interface NodeQuery extends Omit<NodeHover, 'type'> {
Expand Down
2 changes: 1 addition & 1 deletion packages/twoslash/src/types/returns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export interface TwoslashReturnMeta {
/**
* Positions of errors in the code
*/
positionHighlights: Range[]
positionHighlights: [start: number, end: number, text?: string][]
}

export interface ParsedFlagNotation {
Expand Down
1 change: 1 addition & 0 deletions packages/twoslash/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,7 @@ export function findQueryMarkers(
meta.positionHighlights.push([
targetIndex,
targetIndex + markerLength,
match[2]?.trim(),
])
}
})
Expand Down
3 changes: 0 additions & 3 deletions packages/twoslash/test/fixtures/throws/invalid-highlights.ts

This file was deleted.

10 changes: 9 additions & 1 deletion packages/twoslash/test/legacy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ describe('legacy', async () => {
await compareCode('./fixtures/examples/cuts-out-unnecessary-code.ts')
await compareCode('./fixtures/examples/errors-with-generics.ts')
await compareCode('./fixtures/examples/completions-basic.ts')
await compareCode('./fixtures/examples/highlighting.ts')
await compareCode('./fixtures/tests/inline-highlights.ts')

async function compareCode(path: string) {
const code = await fs.readFile(new URL(path, import.meta.url), 'utf-8')
Expand All @@ -19,18 +21,24 @@ describe('legacy', async () => {
function cleanup(t: any) {
delete t.playgroundURL

// We have different calculations for queries, that are not trivial to map back
t.queries.forEach((i: any) => {
// We have different calculations for queries, that are not trivial to map back
delete i.start
delete i.length
delete i.text
delete i.completions
})

t.errors.forEach((i: any) => {
// Id has a bit different calculation, as long as it's unique, it should be fine
delete i.id
})

t.highlights.forEach((i: any) => {
// It seems the legacy version's line numbers are off for the second highlight nations
delete i.line
})

return t
}

Expand Down
8 changes: 3 additions & 5 deletions packages/twoslash/test/results/examples/highlighting.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 2 additions & 5 deletions packages/twoslash/test/results/tests/inline-highlights.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 0 additions & 6 deletions packages/twoslash/test/results/throws/invalid-highlights.txt

This file was deleted.

0 comments on commit 390a92c

Please sign in to comment.