Skip to content

Commit

Permalink
style: Include explicit type declarations on all public APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
eemeli committed Dec 30, 2024
1 parent 4354c42 commit 1ab037d
Show file tree
Hide file tree
Showing 21 changed files with 81 additions and 46 deletions.
22 changes: 18 additions & 4 deletions src/compose/composer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,12 @@ export class Composer<
*
* Mostly useful at the end of input for an empty stream.
*/
streamInfo() {
streamInfo(): {
comment: string
directives: Directives
errors: YAMLParseError[]
warnings: YAMLWarning[]
} {
return {
comment: parsePrelude(this.prelude).comment,
directives: this.directives,
Expand All @@ -148,13 +153,19 @@ export class Composer<
* @param forceDoc - If the stream contains no document, still emit a final document including any comments and directives that would be applied to a subsequent document.
* @param endOffset - Should be set if `forceDoc` is also set, to set the document range end and to indicate errors correctly.
*/
*compose(tokens: Iterable<Token>, forceDoc = false, endOffset = -1) {
*compose(
tokens: Iterable<Token>,
forceDoc = false,
endOffset = -1
): Generator<Document.Parsed<Contents, Strict>, void, unknown> {
for (const token of tokens) yield* this.next(token)
yield* this.end(forceDoc, endOffset)
}

/** Advance the composer by one CST token. */
*next(token: Token) {
*next(
token: Token
): Generator<Document.Parsed<Contents, Strict>, void, unknown> {
if (process.env.LOG_STREAM) console.dir(token, { depth: null })
switch (token.type) {
case 'directive':
Expand Down Expand Up @@ -245,7 +256,10 @@ export class Composer<
* @param forceDoc - If the stream contains no document, still emit a final document including any comments and directives that would be applied to a subsequent document.
* @param endOffset - Should be set if `forceDoc` is also set, to set the document range end and to indicate errors correctly.
*/
*end(forceDoc = false, endOffset = -1) {
*end(
forceDoc = false,
endOffset = -1
): Generator<Document.Parsed<Contents, Strict>, void, unknown> {
if (this.doc) {
this.decorate(this.doc, true)
yield this.doc
Expand Down
2 changes: 1 addition & 1 deletion src/doc/Document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ export class Document<
key: unknown,
value: unknown,
options: CreateNodeOptions = {}
) {
): Pair<K, V> {
const k = this.createNode(key, null, options) as K
const v = this.createNode(value, null, options) as V
return new Pair(k, v)
Expand Down
10 changes: 5 additions & 5 deletions src/doc/directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export class Directives {
* During parsing, get a Directives instance for the current document and
* update the stream state according to the current version's spec.
*/
atDocument() {
atDocument(): Directives {
const res = new Directives(this.yaml, this.tags)
switch (this.yaml.version) {
case '1.1':
Expand All @@ -78,7 +78,7 @@ export class Directives {
add(
line: string,
onError: (offset: number, message: string, warning?: boolean) => void
) {
): boolean {
if (this.atNextDocument) {
this.yaml = { explicit: Directives.defaultYaml.explicit, version: '1.1' }
this.tags = Object.assign({}, Directives.defaultTags)
Expand Down Expand Up @@ -124,7 +124,7 @@ export class Directives {
* @returns Resolved tag, which may also be the non-specific tag `'!'` or a
* `'!local'` tag, or `null` if unresolvable.
*/
tagName(source: string, onError: (message: string) => void) {
tagName(source: string, onError: (message: string) => void): string | null {
if (source === '!') return '!' // non-specific tag

if (source[0] !== '!') {
Expand Down Expand Up @@ -164,15 +164,15 @@ export class Directives {
* Given a fully resolved tag, returns its printable string form,
* taking into account current tag prefixes and defaults.
*/
tagString(tag: string) {
tagString(tag: string): string {
for (const [handle, prefix] of Object.entries(this.tags)) {
if (tag.startsWith(prefix))
return handle + escapeTagName(tag.substring(prefix.length))
}
return tag[0] === '!' ? tag : `!<${tag}>`
}

toString(doc?: Document) {
toString(doc?: Document): string {
const lines = this.yaml.explicit
? [`%YAML ${this.yaml.version || '1.2'}`]
: []
Expand Down
4 changes: 2 additions & 2 deletions src/nodes/Alias.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export class Alias extends NodeBase {
return found
}

toJSON(_arg?: unknown, ctx?: ToJSContext) {
toJSON(_arg?: unknown, ctx?: ToJSContext): unknown {
if (!ctx) return { source: this.source }
const { anchors, doc, maxAliasCount } = ctx
const source = this.resolve(doc)
Expand Down Expand Up @@ -85,7 +85,7 @@ export class Alias extends NodeBase {
ctx?: StringifyContext,
_onComment?: () => void,
_onChompKeep?: () => void
) {
): string {
const src = `*${this.source}`
if (ctx) {
anchorIsValid(this.source)
Expand Down
2 changes: 1 addition & 1 deletion src/nodes/Collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ export abstract class Collection extends NodeBase {
else return isCollection(node) ? node.getIn(rest, keepScalar) : undefined
}

hasAllNullValues(allowScalar?: boolean) {
hasAllNullValues(allowScalar?: boolean): boolean {
return this.items.every(node => {
if (!isPair(node)) return false
const n = node.value
Expand Down
3 changes: 2 additions & 1 deletion src/nodes/Pair.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import type { StringifyContext } from '../stringify/stringify.ts'
import { stringifyPair } from '../stringify/stringifyPair.ts'
import { addPairToJSMap } from './addPairToJSMap.ts'
import { isNode, NODE_TYPE, PAIR } from './identity.ts'
import type { Node } from './Node.ts'
import type { ToJSContext } from './toJS.ts'

export function createPair(
key: unknown,
value: unknown,
ctx: CreateNodeContext
) {
): Pair<Node, Node> {
const k = createNode(key, undefined, ctx)
const v = createNode(value, undefined, ctx)
return new Pair(k, v)
Expand Down
2 changes: 1 addition & 1 deletion src/nodes/Scalar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export class Scalar<T = unknown> extends NodeBase {
return ctx?.keep ? this.value : toJS(this.value, arg, ctx)
}

toString() {
toString(): string {
return String(this.value)
}
}
4 changes: 2 additions & 2 deletions src/nodes/YAMLMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export type MapLike =
export function findPair<K = unknown, V = unknown>(
items: Iterable<Pair<K, V>>,
key: unknown
) {
): Pair<K, V> | undefined {
const k = isScalar(key) ? key.value : key
for (const it of items) {
if (isPair(it)) {
Expand Down Expand Up @@ -57,7 +57,7 @@ export class YAMLMap<K = unknown, V = unknown> extends Collection {
* A generic collection parsing method that can be extended
* to other node classes that inherit from YAMLMap
*/
static from(schema: Schema, obj: unknown, ctx: CreateNodeContext) {
static from(schema: Schema, obj: unknown, ctx: CreateNodeContext): YAMLMap {
const { keepUndefined, replacer } = ctx
const map = new this(schema)
const add = (key: unknown, value: unknown) => {
Expand Down
4 changes: 2 additions & 2 deletions src/nodes/YAMLSeq.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export class YAMLSeq<T = unknown> extends Collection {
else this.items[idx] = value
}

toJSON(_?: unknown, ctx?: ToJSContext) {
toJSON(_?: unknown, ctx?: ToJSContext): unknown[] {
const seq: unknown[] = []
if (ctx?.onCreate) ctx.onCreate(seq)
let i = 0
Expand All @@ -121,7 +121,7 @@ export class YAMLSeq<T = unknown> extends Collection {
})
}

static from(schema: Schema, obj: unknown, ctx: CreateNodeContext) {
static from(schema: Schema, obj: unknown, ctx: CreateNodeContext): YAMLSeq {
const { replacer } = ctx
const seq = new this(schema)
if (obj && Symbol.iterator in Object(obj)) {
Expand Down
2 changes: 1 addition & 1 deletion src/nodes/addPairToJSMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export function addPairToJSMap(
ctx: ToJSContext | undefined,
map: MapLike,
{ key, value }: Pair
) {
): MapLike {
if (isNode(key) && key.addToJSMap) key.addToJSMap(ctx, map, value)
// TODO: Should drop this special case for bare << handling
else if (isMergeKey(ctx, key)) addMergeToJSMap(ctx, map, value)
Expand Down
6 changes: 3 additions & 3 deletions src/parse/cst-stringify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import type { CollectionItem, Token } from './cst.ts'
* Fair warning: This applies no validation whatsoever, and
* simply concatenates the sources in their logical order.
*/
export const stringify = (cst: Token | CollectionItem) =>
export const stringify = (cst: Token | CollectionItem): string =>
'type' in cst ? stringifyToken(cst) : stringifyItem(cst)

function stringifyToken(token: Token) {
function stringifyToken(token: Token): string {
switch (token.type) {
case 'block-scalar': {
let res = ''
Expand Down Expand Up @@ -42,7 +42,7 @@ function stringifyToken(token: Token) {
}
}

function stringifyItem({ start, key, sep, value }: CollectionItem) {
function stringifyItem({ start, key, sep, value }: CollectionItem): string {
let res = ''
for (const st of start) res += st.source
if (key) res += stringifyToken(key)
Expand Down
20 changes: 16 additions & 4 deletions src/parse/cst-visit.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import type { CollectionItem, Document } from './cst.ts'
import type {
BlockMap,
BlockSequence,
CollectionItem,
Document,
FlowCollection
} from './cst.ts'

const BREAK = Symbol('break visit')
const SKIP = Symbol('skip children')
Expand Down Expand Up @@ -39,7 +45,7 @@ export type Visitor = (
* visitor is called on item entry, next visitors are called after handling
* a non-empty `key` and when exiting the item.
*/
export function visit(cst: Document | CollectionItem, visitor: Visitor) {
export function visit(cst: Document | CollectionItem, visitor: Visitor): void {
if ('type' in cst && cst.type === 'document')
cst = { start: cst.start, value: cst.value }
_visit(Object.freeze([]), cst, visitor)
Expand All @@ -59,7 +65,10 @@ visit.SKIP = SKIP as symbol
visit.REMOVE = REMOVE as symbol

/** Find the item at `path` from `cst` as the root */
visit.itemAtPath = (cst: Document | CollectionItem, path: VisitPath) => {
visit.itemAtPath = (
cst: Document | CollectionItem,
path: VisitPath
): CollectionItem | undefined => {
let item: CollectionItem = cst
for (const [field, index] of path) {
const tok = item?.[field]
Expand All @@ -75,7 +84,10 @@ visit.itemAtPath = (cst: Document | CollectionItem, path: VisitPath) => {
*
* Throws an error if the collection is not found, which should never happen if the item itself exists.
*/
visit.parentCollection = (cst: Document | CollectionItem, path: VisitPath) => {
visit.parentCollection = (
cst: Document | CollectionItem,
path: VisitPath
): BlockMap | BlockSequence | FlowCollection => {
const parent = visit.itemAtPath(cst, path.slice(0, -1))
const field = path[path.length - 1][0]
const coll = parent?.[field]
Expand Down
2 changes: 1 addition & 1 deletion src/parse/cst.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ export const isScalar = (

/* istanbul ignore next */
/** Get a printable representation of a lexer token */
export function prettyToken(token: string) {
export function prettyToken(token: string): string {
switch (token) {
case BOM:
return '<BOM>'
Expand Down
2 changes: 1 addition & 1 deletion src/parse/lexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export class Lexer {
*
* @returns A generator of lexical tokens
*/
*lex(source: string, incomplete = false) {
*lex(source: string, incomplete = false): Generator<string, void> {
if (source) {
if (typeof source !== 'string') throw TypeError('source is not a string')
this.buffer = this.buffer ? this.buffer + source : source
Expand Down
4 changes: 2 additions & 2 deletions src/parse/line-counter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ export class LineCounter {
* Should be called in ascending order. Otherwise, call
* `lineCounter.lineStarts.sort()` before calling `linePos()`.
*/
addNewLine = (offset: number) => this.lineStarts.push(offset)
addNewLine = (offset: number): number => this.lineStarts.push(offset)

/**
* Performs a binary search and returns the 1-indexed { line, col }
* position of `offset`. If `line === 0`, `addNewLine` has never been
* called or `offset` is before the first known newline.
*/
linePos = (offset: number) => {
linePos = (offset: number): { line: number; col: number } => {
let low = 0
let high = this.lineStarts.length
while (low < high) {
Expand Down
6 changes: 3 additions & 3 deletions src/parse/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ export class Parser {
*
* @returns A generator of tokens representing each directive, document, and other structure.
*/
*parse(source: string, incomplete = false) {
*parse(source: string, incomplete = false): Generator<Token, void> {
if (this.onNewLine && this.offset === 0) this.onNewLine(0)
for (const lexeme of this.lexer.lex(source, incomplete))
yield* this.next(lexeme)
Expand All @@ -186,7 +186,7 @@ export class Parser {
/**
* Advance the parser by the `source` of one lexical token.
*/
*next(source: string) {
*next(source: string): Generator<Token, void> {
this.source = source
if (env.LOG_TOKENS) console.log('|', prettyToken(source))

Expand Down Expand Up @@ -237,7 +237,7 @@ export class Parser {
private lexer = new Lexer();

/** Call at end of input to push out any remaining constructions */
*end() {
*end(): Generator<Token, void> {
while (this.stack.length > 0) yield* this.pop()
}

Expand Down
18 changes: 11 additions & 7 deletions src/schema/yaml-1.1/omap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ export class YAMLOMap extends YAMLSeq {
this.tag = YAMLOMap.tag
}

add = YAMLMap.prototype.add.bind(this)
delete = YAMLMap.prototype.delete.bind(this)
get = YAMLMap.prototype.get.bind(this)
has = YAMLMap.prototype.has.bind(this)
set = YAMLMap.prototype.set.bind(this)
add: typeof YAMLMap.prototype.add = YAMLMap.prototype.add.bind(this)
delete: typeof YAMLMap.prototype.delete = YAMLMap.prototype.delete.bind(this)
get: typeof YAMLMap.prototype.get = YAMLMap.prototype.get.bind(this)
has: typeof YAMLMap.prototype.has = YAMLMap.prototype.has.bind(this)
set: typeof YAMLMap.prototype.set = YAMLMap.prototype.set.bind(this)

/**
* If `ctx` is given, the return type is actually `Map<unknown, unknown>`,
* but TypeScript won't allow widening the signature of a child method.
*/
toJSON(_?: unknown, ctx?: ToJSContext) {
toJSON(_?: unknown, ctx?: ToJSContext): unknown[] {
if (!ctx) return super.toJSON(_)
const map = new Map()
if (ctx?.onCreate) ctx.onCreate(map)
Expand All @@ -45,7 +45,11 @@ export class YAMLOMap extends YAMLSeq {
return map as unknown as unknown[]
}

static from(schema: Schema, iterable: unknown, ctx: CreateNodeContext) {
static from(
schema: Schema,
iterable: unknown,
ctx: CreateNodeContext
): YAMLOMap {
const pairs = createPairs(schema, iterable, ctx)
const omap = new this()
omap.items = pairs.items
Expand Down
8 changes: 6 additions & 2 deletions src/schema/yaml-1.1/set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export class YAMLSet<T = unknown> extends YAMLMap<T, Scalar<null> | null> {
ctx?: StringifyContext,
onComment?: () => void,
onChompKeep?: () => void
) {
): string {
if (!ctx) return JSON.stringify(this)
if (this.hasAllNullValues(true))
return super.toString(
Expand All @@ -87,7 +87,11 @@ export class YAMLSet<T = unknown> extends YAMLMap<T, Scalar<null> | null> {
else throw new Error('Set items must all have null values')
}

static from(schema: Schema, iterable: unknown, ctx: CreateNodeContext) {
static from(
schema: Schema,
iterable: unknown,
ctx: CreateNodeContext
): YAMLSet {
const { replacer } = ctx
const set = new this(schema)
if (iterable && Symbol.iterator in Object(iterable))
Expand Down
2 changes: 1 addition & 1 deletion src/stringify/foldFlowLines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export function foldFlowLines(
onFold,
onOverflow
}: FoldOptions = {}
) {
): string {
if (!lineWidth || lineWidth < 0) return text
if (lineWidth < minContentWidth) minContentWidth = 0
const endStep = Math.max(1 + minContentWidth, 1 + lineWidth - indent.length)
Expand Down
Loading

0 comments on commit 1ab037d

Please sign in to comment.