Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug fixes #106

Merged
merged 1 commit into from Apr 8, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/ast.ts
Expand Up @@ -96,7 +96,7 @@ export interface YAMLWithMeta extends BaseYAMLNode {
type: "YAMLWithMeta"
anchor: YAMLAnchor | null
tag: YAMLTag | null
value: YAMLContent | null
value: Exclude<YAMLContent, YAMLAlias> | null
parent: YAMLDocument | YAMLPair | YAMLSequence
}

Expand Down
91 changes: 40 additions & 51 deletions src/convert.ts
Expand Up @@ -616,15 +616,15 @@ function convertMapping(
function convertFlowCollection(
preTokens: PreTokens,
cst: CST.FlowCollection,
node: ParsedNode,
node: ParsedNode | PairParsed,
ctx: Context,
parent: YAMLDocument | YAMLPair | YAMLBlockSequence | YAMLFlowSequence,
doc: YAMLDocument,
): YAMLFlowMapping | YAMLFlowSequence | YAMLWithMeta {
if (cst.start.type === "flow-map-start") {
const startToken = ctx.addToken("Punctuator", toRange(cst.start))
/* istanbul ignore if */
if (!isMap(node)) {
if (!isMap(node) && !isPair(node)) {
throw ctx.throwError(
`unknown error: AST is not Map and Pair (${getNodeType(
node,
Expand Down Expand Up @@ -678,7 +678,7 @@ function convertFlowMapping(
preTokens: PreTokens,
startToken: Token,
cst: CST.FlowCollection,
node: YAMLMap.Parsed,
node: YAMLMap.Parsed | PairParsed,
ctx: Context,
parent: YAMLDocument | YAMLPair | YAMLBlockSequence | YAMLFlowSequence,
doc: YAMLDocument,
Expand All @@ -691,7 +691,7 @@ function convertFlowMapping(
parent,
...loc,
}
const items = [...node.items]
const items = getPairs(node)
let lastToken
for (const item of cst.items) {
const startTokens = new PreTokens(item.start, ctx)
Expand Down Expand Up @@ -979,15 +979,7 @@ function convertMappingKey(
preTokens.first() ?? indexForError,
)
}
return convertAnchorAndTag<YAMLContent>(
preTokens,
node,
ctx,
parent,
null,
doc,
null,
)
return convertAnchorAndTag(preTokens, node, ctx, parent, null, doc, null)
}

/**
Expand Down Expand Up @@ -1015,15 +1007,7 @@ function convertMappingValue(
preTokens.first() ?? indexForError,
)
}
return convertAnchorAndTag<YAMLContent>(
preTokens,
node,
ctx,
parent,
null,
doc,
null,
)
return convertAnchorAndTag(preTokens, node, ctx, parent, null, doc, null)
}

/**
Expand Down Expand Up @@ -1113,13 +1097,30 @@ function convertSequenceItem(
}
if (cst.value) {
if (isPair(node)) {
if (cst.value.type !== "block-map") {
throw ctx.throwError(
`unknown error: CST is not block map (${cst.value.type}). Unable to process Pair AST.`,
if (cst.value.type === "block-map") {
return convertMapping(
preTokens,
cst.value,
node,
ctx,
parent,
doc,
)
}
if (cst.value.type === "flow-collection") {
return convertFlowCollection(
preTokens,
cst.value,
node,
ctx,
parent,
doc,
)
}
return convertMapping(preTokens, cst.value, node, ctx, parent, doc)
throw ctx.throwError(
`unknown error: CST is not block-map and flow-collection (${cst.value.type}). Unable to process Pair AST.`,
cst.value,
)
}
return convertContentNode(preTokens, cst.value, node, ctx, parent, doc)
}
Expand All @@ -1132,15 +1133,7 @@ function convertSequenceItem(
preTokens.first() ?? indexForError,
)
}
return convertAnchorAndTag<YAMLContent>(
preTokens,
node,
ctx,
parent,
null,
doc,
null,
)
return convertAnchorAndTag(preTokens, node, ctx, parent, null, doc, null)
}

/**
Expand Down Expand Up @@ -1168,15 +1161,7 @@ function convertFlowSequenceItem(
preTokens.first() ?? indexForError,
)
}
return convertAnchorAndTag<YAMLContent>(
preTokens,
node,
ctx,
parent,
null,
doc,
null,
)
return convertAnchorAndTag(preTokens, node, ctx, parent, null, doc, null)
}

/**
Expand Down Expand Up @@ -1242,8 +1227,8 @@ function convertPlain(
version: YAMLVersion,
): string | number | boolean | null {
for (const tagResolver of tagResolvers[version]) {
if (tagResolver.test(str)) {
return tagResolver.resolve(str)
if (tagResolver.testString(str)) {
return tagResolver.resolveString(str)
}
}
return str
Expand Down Expand Up @@ -1416,14 +1401,14 @@ function getBlockEnd(end: number, ctx: Context): number {
function convertAlias(
preTokens: PreTokens,
cst: CST.FlowScalar & { type: "alias" },
node: Alias.Parsed,
_node: Alias.Parsed,
ctx: Context,
parent: YAMLDocument | YAMLPair | YAMLBlockSequence | YAMLFlowSequence,
doc: YAMLDocument,
_doc: YAMLDocument,
): YAMLAlias | YAMLWithMeta {
const [start, end] = toRange(cst)
const loc = ctx.getConvertLocation(start, ctx.lastSkipSpaces(start, end))
let ast: YAMLAlias | YAMLWithMeta = {
const ast: YAMLAlias | YAMLWithMeta = {
type: "YAMLAlias",
name: cst.source.slice(1),
parent,
Expand All @@ -1434,7 +1419,11 @@ function convertAlias(
if (tokenRange[0] < tokenRange[1]) {
ctx.addToken("Identifier", tokenRange)
}
ast = convertAnchorAndTag(preTokens, node, ctx, parent, ast, doc, ast)
const token = preTokens.first()
/* istanbul ignore if */
if (token) {
throw ctx.throwUnexpectedTokenError(token)
}

cst.end?.forEach((t) => processAnyToken(t, ctx))

Expand All @@ -1444,7 +1433,7 @@ function convertAlias(
/**
* Convert Anchor and Tag
*/
function convertAnchorAndTag<V extends YAMLContent>(
function convertAnchorAndTag<V extends NonNullable<YAMLWithMeta["value"]>>(
preTokens: PreTokens,
node:
| Scalar
Expand Down
12 changes: 10 additions & 2 deletions src/tags/commons.ts
@@ -1,5 +1,13 @@
import type { YAMLAlias, YAMLContent } from "../ast"

export type TagResolver<T> = {
tag: string
test: (str: string) => boolean
resolve: (str: string) => T
testString: (str: string) => boolean
resolveString: (str: string) => T
}

export type TagNodeResolver<T> = {
tag: string
testNode: (node: Exclude<YAMLContent, YAMLAlias>) => boolean
resolveNode: (node: Exclude<YAMLContent, YAMLAlias>) => T
}
15 changes: 13 additions & 2 deletions src/tags/index.ts
@@ -1,8 +1,19 @@
import { tagResolvers as tagResolversFor1_2 } from "./tags1.2"
import { tagResolvers as tagResolversFor1_1 } from "./tags1.1"
import {
tagResolvers as tagResolversFor1_2,
tagNodeResolvers as tagNodeResolversFor1_2,
} from "./tags1.2"
import {
tagResolvers as tagResolversFor1_1,
tagNodeResolvers as tagNodeResolversFor1_1,
} from "./tags1.1"

export const tagResolvers = {
"1.3": tagResolversFor1_2,
"1.2": tagResolversFor1_2,
"1.1": tagResolversFor1_1,
}
export const tagNodeResolvers = {
"1.3": tagNodeResolversFor1_2,
"1.2": tagNodeResolversFor1_2,
"1.1": tagNodeResolversFor1_1,
}
29 changes: 29 additions & 0 deletions src/tags/omap.ts
@@ -0,0 +1,29 @@
import type { YAMLMapping, YAMLSequence } from "../ast"
import { getStaticYAMLValue } from "../utils"
import type { TagNodeResolver } from "./commons"

export const OMAP: TagNodeResolver<Record<any, any>> = {
// see https://yaml.org/type/omap.html
tag: "tag:yaml.org,2002:omap",
testNode(node) {
return (
node.type === "YAMLSequence" &&
node.entries.every(
(e) => e?.type === "YAMLMapping" && e.pairs.length === 1,
)
)
},
resolveNode(node) {
const seq = node as YAMLSequence
const result: Record<any, any> = {}
for (const e of seq.entries) {
const map = e as YAMLMapping
for (const p of map.pairs) {
const key = p.key ? getStaticYAMLValue(p.key) : p.key
const value = p.value ? getStaticYAMLValue(p.value) : p.value
result[key as any] = value
}
}
return result
},
}
22 changes: 22 additions & 0 deletions src/tags/set.ts
@@ -0,0 +1,22 @@
import type { YAMLMapping } from "../ast"
import { getStaticYAMLValue } from "../utils"
import type { TagNodeResolver } from "./commons"

export const SET: TagNodeResolver<any[]> = {
// see https://yaml.org/type/set.html
tag: "tag:yaml.org,2002:set",
testNode(node) {
return (
node.type === "YAMLMapping" &&
node.pairs.every((p) => p.key != null && p.value == null)
)
},
resolveNode(node) {
const map = node as YAMLMapping
const result = []
for (const p of map.pairs) {
result.push(getStaticYAMLValue(p.key!))
}
return result
},
}