Skip to content
Merged
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
6 changes: 5 additions & 1 deletion src/codegen/browser/code/comment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import { AST_NODE_TYPES, TSESTree as ts } from '@typescript-eslint/types'

import { baseProps } from '@/codegen/estree/nodes'

export function comment(value: string): ts.BlockStatement {
export function comment(
value: string,
newLine: ts.NewLine = { after: 'never' }
): ts.BlockStatement {
// The type of node here is not important since it's just being used as
// a placeholder for the comment. A BlockStatement just happens to be one
// of the simplest nodes to build.
Expand All @@ -11,5 +14,6 @@ export function comment(value: string): ts.BlockStatement {
type: AST_NODE_TYPES.BlockStatement,
comment: value,
body: [],
newLine,
}
}
6 changes: 4 additions & 2 deletions src/codegen/browser/code/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,11 @@ export function toTypeScriptAst(test: ir.Test): ts.Program {
...scenarios.filter((item) => item !== undefined),
])

const header = spaceAfter([comment(generateScriptHeader())])
const header = comment(generateScriptHeader(), {
after: true,
})

return program({
body: [...header, ...imports, ...exports],
body: [header, ...imports, ...exports],
})
}
18 changes: 5 additions & 13 deletions src/codegen/browser/formatting/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,11 @@ declare module 'prettier/plugins/estree' {
}

function applySpacing(node: ts.Node | null, doc: builders.Doc): builders.Doc {
if (node?.newLine === 'before') {
return [hardline, doc]
}

if (node?.newLine === 'after') {
return [doc, hardline]
}

if (node?.newLine === 'both') {
return [hardline, doc, hardline]
}

return doc
return [
node?.newLine?.before === true && hardline,
doc,
node?.newLine?.after === true && hardline,
].filter((item) => item !== false)
}

/**
Expand Down
61 changes: 45 additions & 16 deletions src/codegen/browser/formatting/spacing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,63 @@ import type { TSESTree as ts } from '@typescript-eslint/types'
export function trimBefore(
newLine: ts.NewLine | undefined
): ts.NewLine | undefined {
return newLine === 'both' ? 'after' : undefined
if (newLine === undefined) {
return undefined
}

return {
...newLine,
before: newLine.before === true ? false : newLine.before,
}
}

export function trimAfter(
newLine: ts.NewLine | undefined
): ts.NewLine | undefined {
return newLine === 'both' ? 'before' : undefined
if (newLine === undefined) {
return undefined
}

return {
...newLine,
after: newLine.after === true ? false : newLine.after,
}
}

export function mergeNewLine(
newLine: ts.NewLine | undefined,
target: ts.NewLine
target: ts.NewLine | undefined,
newLine: ts.NewLine
): ts.NewLine {
if (newLine === target) {
if (target === undefined) {
return newLine
}

if (newLine === undefined) {
return target
}

return 'both'
const before =
newLine.before !== undefined
? target.before === 'never'
? 'never'
: newLine.before
: target.before

const after =
newLine.after !== undefined
? target.after === 'never'
? 'never'
: newLine.after
: target.after

return { before, after }
}

export function spaceBetween<T extends ts.Node>(nodes: T[]) {
return nodes.map((node, index) => {
if (index === nodes.length - 1) {
const nextNode = nodes[index + 1]

if (nextNode === undefined || nextNode.newLine?.before === 'never') {
return node
}

return { ...node, newLine: mergeNewLine(node.newLine, 'after') }
return { ...node, newLine: mergeNewLine(node.newLine, { after: true }) }
})
}

Expand All @@ -46,7 +72,7 @@ export function spaceAfter<T extends ts.Node>(nodes: T[]): T[] {

return [
...nodes.slice(0, -1),
{ ...last, newLine: mergeNewLine(last.newLine, 'after') },
{ ...last, newLine: mergeNewLine(last.newLine, { after: true }) },
]
}

Expand All @@ -64,9 +90,9 @@ export function spaceAround<T extends ts.Node>([first, ...rest]: T[]): T[] {
const middle = rest.slice(0, -1)

return [
{ ...first, newLine: mergeNewLine(first.newLine, 'before') },
{ ...first, newLine: mergeNewLine(first.newLine, { before: true }) },
...middle,
{ ...last, newLine: mergeNewLine(last.newLine, 'after') },
{ ...last, newLine: mergeNewLine(last.newLine, { after: true }) },
]
}

Expand All @@ -75,7 +101,10 @@ export function spaceBefore<T extends ts.Node>([first, ...rest]: T[]): T[] {
return []
}

return [{ ...first, newLine: mergeNewLine(first.newLine, 'before') }, ...rest]
return [
{ ...first, newLine: mergeNewLine(first.newLine, { before: true }) },
...rest,
]
}

export function trimSpacing<T extends ts.Node>([first, ...rest]: T[]): T[] {
Expand Down
12 changes: 11 additions & 1 deletion src/codegen/estree/typescript-estree.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
declare module '@typescript-eslint/types' {
namespace TSESTree {
type NewLine = 'before' | 'after' | 'both'
/**
* Options for specifying new line behavior around a node. Specifying
* `"never"` will prevent any new lines from being added in that position,
* even if other formatting rules would normally add them.
*/
type NewLineOption = boolean | 'never'

type NewLine = {
before?: NewLineOption
after?: NewLineOption
}

interface NodeOrTokenData {
/**
Expand Down