mirror of https://github.com/status-im/NimYAML.git
Reworked some exceptions and compiler warnings
* LexerError is properly rewritten as YamlParserError in parser * updated some code to remove warnings and hints that got emitted * Fixes #129
This commit is contained in:
parent
ab3ff9fad4
commit
034b9b8453
|
@ -17,16 +17,16 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1653936696,
|
||||
"narHash": "sha256-M6bJShji9AIDZ7Kh7CPwPBPb/T7RiVev2PAcOi4fxDQ=",
|
||||
"lastModified": 1669833724,
|
||||
"narHash": "sha256-/HEZNyGbnQecrgJnfE8d0WC5c1xuPSD2LUpB6YXlg4c=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "ce6aa13369b667ac2542593170993504932eb836",
|
||||
"rev": "4d2b37a84fad1091b9de401eb450aae66f1a741e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "22.05",
|
||||
"ref": "22.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/22.05";
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/22.11";
|
||||
utils.url = "github:numtide/flake-utils";
|
||||
nix-filter.url = "github:numtide/nix-filter";
|
||||
};
|
||||
|
|
|
@ -3,8 +3,8 @@ import unittest
|
|||
|
||||
type
|
||||
Config = ref object
|
||||
docs_root* {.defaultVal: "~/.example".}: string
|
||||
drafts_root*: string
|
||||
docsRoot* {.defaultVal: "~/.example".}: string
|
||||
draftsRoot*: string
|
||||
|
||||
Stuff = ref object
|
||||
a {.transient.}: string
|
||||
|
@ -32,11 +32,11 @@ type
|
|||
|
||||
suite "Serialization Annotations":
|
||||
test "load default value":
|
||||
let input = "drafts_root: foo"
|
||||
let input = "draftsRoot: foo"
|
||||
var result: Config
|
||||
load(input, result)
|
||||
assert result.docs_root == "~/.example", "docs_root is " & result.docs_root
|
||||
assert result.drafts_root == "foo", "drafts_root is " & result.drafts_root
|
||||
assert result.docsRoot == "~/.example", "docsRoot is " & result.docsRoot
|
||||
assert result.draftsRoot == "foo", "draftsRoot is " & result.draftsRoot
|
||||
|
||||
test "load into object with transient fields":
|
||||
let input = "b: warbl"
|
||||
|
|
|
@ -11,75 +11,75 @@ suite "DOM":
|
|||
test "Composing simple Scalar":
|
||||
let
|
||||
input = newStringStream("scalar")
|
||||
result = loadDOM(input)
|
||||
assert result.root.kind == yScalar
|
||||
assert result.root.content == "scalar"
|
||||
assert result.root.tag == yTagQuestionMark
|
||||
result = loadAs[YamlNode](input)
|
||||
assert result.kind == yScalar
|
||||
assert result.content == "scalar"
|
||||
assert result.tag == yTagQuestionMark
|
||||
test "Serializing simple Scalar":
|
||||
let input = initYamlDoc(newYamlNode("scalar"))
|
||||
var result = serialize(input)
|
||||
let input = newYamlNode("scalar")
|
||||
var result = represent(input)
|
||||
ensure(result, startStreamEvent(), startDocEvent(), scalarEvent("scalar"),
|
||||
endDocEvent(), endStreamEvent())
|
||||
test "Composing sequence":
|
||||
let
|
||||
input = newStringStream("- !!str a\n- !!bool no")
|
||||
result = loadDOM(input)
|
||||
assert result.root.kind == ySequence
|
||||
assert result.root.tag == yTagQuestionMark
|
||||
assert result.root.len == 2
|
||||
assert result.root[0].kind == yScalar
|
||||
assert result.root[0].tag == yTagString
|
||||
assert result.root[0].content == "a"
|
||||
assert result.root[1].kind == yScalar
|
||||
assert result.root[1].tag == yTagBoolean
|
||||
assert result.root[1].content == "no"
|
||||
result = loadAs[YamlNode](input)
|
||||
assert result.kind == ySequence
|
||||
assert result.tag == yTagQuestionMark
|
||||
assert result.len == 2
|
||||
assert result[0].kind == yScalar
|
||||
assert result[0].tag == yTagString
|
||||
assert result[0].content == "a"
|
||||
assert result[1].kind == yScalar
|
||||
assert result[1].tag == yTagBoolean
|
||||
assert result[1].content == "no"
|
||||
test "Serializing sequence":
|
||||
let input = initYamlDoc(newYamlNode([
|
||||
let input = newYamlNode([
|
||||
newYamlNode("a", yTagString),
|
||||
newYamlNode("no", yTagBoolean)]))
|
||||
var result = serialize(input)
|
||||
newYamlNode("no", yTagBoolean)])
|
||||
var result = represent(input, tsAll)
|
||||
ensure(result, startStreamEvent(), startDocEvent(), startSeqEvent(),
|
||||
scalarEvent("a", yTagString), scalarEvent("no", yTagBoolean),
|
||||
endSeqEvent(), endDocEvent(), endStreamEvent())
|
||||
test "Composing mapping":
|
||||
let
|
||||
input = newStringStream("--- !!map\n!foo bar: [a, b]")
|
||||
result = loadDOM(input)
|
||||
assert result.root.kind == yMapping
|
||||
assert result.root.tag == yTagMapping
|
||||
assert result.root.fields.len == 1
|
||||
for key, value in result.root.fields.pairs:
|
||||
result = loadAs[YamlNode](input)
|
||||
assert result.kind == yMapping
|
||||
assert result.tag == yTagMapping
|
||||
assert result.fields.len == 1
|
||||
for key, value in result.fields.pairs:
|
||||
assert key.kind == yScalar
|
||||
assert $key.tag == "!foo"
|
||||
assert key.content == "bar"
|
||||
assert value.kind == ySequence
|
||||
assert value.len == 2
|
||||
test "Serializing mapping":
|
||||
let input = initYamlDoc(newYamlNode([
|
||||
let input = newYamlNode([
|
||||
(key: newYamlNode("bar"), value: newYamlNode([newYamlNode("a"),
|
||||
newYamlNode("b")]))]))
|
||||
var result = serialize(input)
|
||||
newYamlNode("b")]))])
|
||||
var result = represent(input)
|
||||
ensure(result, startStreamEvent(), startDocEvent(), startMapEvent(),
|
||||
scalarEvent("bar"), startSeqEvent(), scalarEvent("a"), scalarEvent("b"),
|
||||
endSeqEvent(), endMapEvent(), endDocEvent(), endStreamEvent())
|
||||
test "Composing with anchors":
|
||||
let
|
||||
input = newStringStream("- &a foo\n- &b bar\n- *a\n- *b")
|
||||
result = loadDOM(input)
|
||||
assert result.root.kind == ySequence
|
||||
assert result.root.len == 4
|
||||
assert result.root[0].kind == yScalar
|
||||
assert result.root[0].content == "foo"
|
||||
assert result.root[1].kind == yScalar
|
||||
assert result.root[1].content == "bar"
|
||||
assert cast[pointer](result.root[0]) == cast[pointer](result.root[2])
|
||||
assert cast[pointer](result.root[1]) == cast[pointer](result.root[3])
|
||||
result = loadAs[YamlNode](input)
|
||||
assert result.kind == ySequence
|
||||
assert result.len == 4
|
||||
assert result[0].kind == yScalar
|
||||
assert result[0].content == "foo"
|
||||
assert result[1].kind == yScalar
|
||||
assert result[1].content == "bar"
|
||||
assert cast[pointer](result[0]) == cast[pointer](result[2])
|
||||
assert cast[pointer](result[1]) == cast[pointer](result[3])
|
||||
test "Serializing with anchors":
|
||||
let
|
||||
a = newYamlNode("a")
|
||||
b = newYamlNode("b")
|
||||
input = initYamlDoc(newYamlNode([a, b, newYamlNode("c"), a, b]))
|
||||
var result = serialize(input)
|
||||
input = newYamlNode([a, b, newYamlNode("c"), a, b])
|
||||
var result = represent(input)
|
||||
ensure(result, startStreamEvent(), startDocEvent(), startSeqEvent(),
|
||||
scalarEvent("a", anchor="a".Anchor),
|
||||
scalarEvent("b", anchor="b".Anchor), scalarEvent("c"),
|
||||
|
@ -88,8 +88,8 @@ suite "DOM":
|
|||
test "Serializing with all anchors":
|
||||
let
|
||||
a = newYamlNode("a")
|
||||
input = initYamlDoc(newYamlNode([a, newYamlNode("b"), a]))
|
||||
var result = serialize(input, asAlways)
|
||||
input = newYamlNode([a, newYamlNode("b"), a])
|
||||
var result = represent(input, a = asAlways)
|
||||
ensure(result, startStreamEvent(), startDocEvent(),
|
||||
startSeqEvent(anchor="a".Anchor),
|
||||
scalarEvent("a", anchor = "b".Anchor),
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
|
||||
|
||||
{.warning[UnusedImport]: off.}
|
||||
import tlex, tjson, tserialization, tparser, tquickstart, tannotations
|
||||
|
||||
when not defined(gcArc) or defined(gcOrc):
|
||||
|
|
|
@ -37,7 +37,7 @@ type
|
|||
yScalar, yMapping, ySequence
|
||||
|
||||
YamlNode* = ref YamlNodeObj
|
||||
## Represents a node in a ``YamlDocument``.
|
||||
## Represents a node in a YAML document
|
||||
|
||||
YamlNodeObj* = object
|
||||
tag*: Tag
|
||||
|
@ -150,8 +150,10 @@ proc newYamlNode*(fields: openarray[(YamlNode, YamlNode)],
|
|||
YamlNode(kind: yMapping, fields: newTable(fields), tag: tag,
|
||||
startPos: startPos, endPos: endPos)
|
||||
|
||||
{.push warning[Deprecated]: off.}
|
||||
proc initYamlDoc*(root: YamlNode): YamlDocument =
|
||||
result = YamlDocument(root: root)
|
||||
{.pop.}
|
||||
|
||||
proc constructChild*(s: var YamlStream, c: ConstructionContext,
|
||||
result: var YamlNode)
|
||||
|
@ -210,6 +212,7 @@ proc constructChild*(s: var YamlStream, c: ConstructionContext,
|
|||
result = cast[YamlNode](c.refs.getOrDefault(start.aliasTarget).p)
|
||||
else: internalError("Malformed YamlStream")
|
||||
|
||||
{.push warning[Deprecated]: off.}
|
||||
proc compose*(s: var YamlStream): YamlDocument
|
||||
{.raises: [YamlStreamError, YamlConstructionError],
|
||||
deprecated: "use construct(s, root) instead".} =
|
||||
|
@ -243,6 +246,7 @@ proc loadMultiDom*(s: Stream | string): seq[YamlDocument]
|
|||
elif ex.parent of OSError:
|
||||
raise (ref OSError)(ex.parent)
|
||||
else: internalError("Unexpected exception: " & ex.parent.repr)
|
||||
{.pop.}
|
||||
|
||||
proc representChild*(value: YamlNodeObj, ts: TagStyle,
|
||||
c: SerializationContext) {.raises: [YamlSerializationError].} =
|
||||
|
@ -264,6 +268,7 @@ proc representChild*(value: YamlNodeObj, ts: TagStyle,
|
|||
representChild(value, childTagStyle, c)
|
||||
c.put(endMapEvent())
|
||||
|
||||
{.push warning[Deprecated]: off.}
|
||||
proc serialize*(doc: YamlDocument, a: AnchorStyle = asTidy): YamlStream
|
||||
{.deprecated: "use represent[YamlNode] instead".} =
|
||||
result = represent(doc.root, tsAll, a = a, handles = @[])
|
||||
|
@ -275,6 +280,7 @@ proc dumpDom*(doc: YamlDocument, target: Stream,
|
|||
## Dump a YamlDocument as YAML character stream.
|
||||
dump(doc.root, target, tsAll, anchorStyle = anchorStyle, options = options,
|
||||
handles = @[])
|
||||
{.pop.}
|
||||
|
||||
proc `[]`*(node: YamlNode, i: int): YamlNode =
|
||||
## Get the node at index *i* from a sequence. *node* must be a *ySequence*.
|
||||
|
|
110
yaml/parser.nim
110
yaml/parser.nim
|
@ -200,12 +200,20 @@ proc generateError(c: Context, message: string):
|
|||
msg: message, parent: nil, mark: c.lex.curStartPos,
|
||||
lineContent: c.lex.currentLine())
|
||||
|
||||
proc safeNext(c: Context) =
|
||||
try:
|
||||
c.lex.next()
|
||||
except LexerError as e:
|
||||
raise (ref YamlParserError)(
|
||||
msg: e.msg, parent: nil, mark: (e.line, e.column),
|
||||
lineContent: e.lineContent)
|
||||
|
||||
proc parseTag(c: Context): Tag =
|
||||
let handle = c.lex.fullLexeme()
|
||||
var uri = c.resolveHandle(handle)
|
||||
if uri == "":
|
||||
raise c.generateError("unknown handle: " & escape(handle))
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
if c.lex.cur != Token.Suffix:
|
||||
raise c.generateError("unexpected token (expected tag suffix): " & $c.lex.cur)
|
||||
uri.add(c.lex.evaluated)
|
||||
|
@ -242,7 +250,7 @@ proc atStreamStart(c: Context, e: var Event): bool =
|
|||
c.transition(atStreamEnd)
|
||||
c.pushLevel(beforeDoc, -1)
|
||||
e = Event(startPos: c.lex.curStartPos, endPos: c.lex.curStartPos, kind: yamlStartStream)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
resetHandles(c.handles)
|
||||
return true
|
||||
|
||||
|
@ -259,10 +267,10 @@ proc beforeDoc(c: Context, e: var Event): bool =
|
|||
of DocumentEnd:
|
||||
if seenDirectives:
|
||||
raise c.generateError("Missing `---` after directives")
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
of DirectivesEnd:
|
||||
e = startDocEvent(true, version, c.handles, c.lex.curStartPos, c.lex.curEndPos)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
c.transition(beforeDocEnd)
|
||||
c.pushLevel(afterDirectivesEnd, -1)
|
||||
return true
|
||||
|
@ -278,7 +286,7 @@ proc beforeDoc(c: Context, e: var Event): bool =
|
|||
return true
|
||||
of YamlDirective:
|
||||
seenDirectives = true
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
if c.lex.cur != Token.DirectiveParam:
|
||||
raise c.generateError("Invalid token (expected YAML version string): " & $c.lex.cur)
|
||||
elif version != "":
|
||||
|
@ -286,23 +294,23 @@ proc beforeDoc(c: Context, e: var Event): bool =
|
|||
version = c.lex.fullLexeme()
|
||||
if version != "1.2" and c.issueWarnings:
|
||||
discard # TODO
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
of TagDirective:
|
||||
seenDirectives = true
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
if c.lex.cur != Token.TagHandle:
|
||||
raise c.generateError("Invalid token (expected tag handle): " & $c.lex.cur)
|
||||
let tagHandle = c.lex.fullLexeme()
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
if c.lex.cur != Token.Suffix:
|
||||
raise c.generateError("Invalid token (expected tag URI): " & $c.lex.cur)
|
||||
discard registerHandle(c.handles, tagHandle, c.lex.evaluated)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
of UnknownDirective:
|
||||
seenDirectives = true
|
||||
# TODO: issue warning
|
||||
while true:
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
if c.lex.cur != Token.DirectiveParam: break
|
||||
else:
|
||||
raise c.generateError("Unexpected token (expected directive or document start): " & $c.lex.cur)
|
||||
|
@ -326,7 +334,7 @@ proc afterDirectivesEnd(c: Context, e: var Event): bool =
|
|||
e = scalarEvent(c.lex.evaluated, autoScalarTag(c.inlineProps, c.lex.cur),
|
||||
toStyle(c.lex.cur), c.lex.curStartPos, c.lex.curEndPos)
|
||||
c.popLevel()
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
return true
|
||||
else:
|
||||
raise c.generateError("Illegal content at `---`: " & $c.lex.cur)
|
||||
|
@ -337,7 +345,7 @@ proc beforeImplicitRoot(c: Context, e: var Event): bool =
|
|||
c.inlineStart = c.lex.curEndPos
|
||||
c.headerStart = c.lex.curEndPos
|
||||
c.updateIndentation(c.lex.recentIndentation())
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
case c.lex.cur
|
||||
of SeqItemInd, MapKeyInd, MapValueInd:
|
||||
c.transition(afterCompactParent)
|
||||
|
@ -378,7 +386,7 @@ proc atBlockIndentation(c: Context, e: var Event): bool =
|
|||
c.transition(inBlockSeq, c.lex.recentIndentation())
|
||||
c.pushLevel(beforeBlockIndentation)
|
||||
c.pushLevel(afterCompactParent, c.lex.recentIndentation())
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
return true
|
||||
of MapKeyInd:
|
||||
e = startMapEvent(csBlock, c.headerProps,
|
||||
|
@ -387,7 +395,7 @@ proc atBlockIndentation(c: Context, e: var Event): bool =
|
|||
c.transition(beforeBlockMapValue, c.lex.recentIndentation())
|
||||
c.pushLevel(beforeBlockIndentation)
|
||||
c.pushLevel(afterCompactParent, c.lex.recentIndentation())
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
return true
|
||||
of Plain, SingleQuoted, DoubleQuoted:
|
||||
c.updateIndentation(c.lex.recentIndentation())
|
||||
|
@ -396,7 +404,7 @@ proc atBlockIndentation(c: Context, e: var Event): bool =
|
|||
toStyle(c.lex.cur), c.inlineStart, c.lex.curEndPos)
|
||||
c.headerProps = defaultProperties
|
||||
let headerEnd = c.lex.curStartPos
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
if c.lex.cur == Token.MapValueInd:
|
||||
if c.lex.lastScalarWasMultiline():
|
||||
raise c.generateError("Implicit mapping key may not be multiline")
|
||||
|
@ -414,7 +422,7 @@ proc atBlockIndentation(c: Context, e: var Event): bool =
|
|||
e = aliasEvent(c.lex.shortLexeme().Anchor, c.inlineStart, c.lex.curEndPos)
|
||||
c.inlineProps = defaultProperties
|
||||
let headerEnd = c.lex.curStartPos
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
if c.lex.cur == Token.MapValueInd:
|
||||
c.keyCache.add(move(e))
|
||||
e = startMapEvent(csBlock, c.headerProps, c.headerStart, headerEnd)
|
||||
|
@ -446,7 +454,7 @@ proc atBlockIndentationProps(c: Context, e: var Event): bool =
|
|||
toStyle(c.lex.cur), c.inlineStart, c.lex.curEndPos)
|
||||
c.inlineProps = defaultProperties
|
||||
let headerEnd = c.lex.curStartPos
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
if c.lex.cur == Token.MapValueInd:
|
||||
if c.lex.lastScalarWasMultiline():
|
||||
raise c.generateError("Implicit mapping key may not be multiline")
|
||||
|
@ -485,11 +493,11 @@ proc atBlockIndentationProps(c: Context, e: var Event): bool =
|
|||
e = scalarEvent(c.lex.evaluated, c.headerProps, toStyle(c.lex.cur),
|
||||
c.inlineStart, c.lex.curEndPos)
|
||||
c.headerProps = defaultProperties
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
c.popLevel()
|
||||
return true
|
||||
of Indentation:
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
c.transition(atBlockIndentation)
|
||||
return false
|
||||
of StreamEnd, DocumentEnd, DirectivesEnd:
|
||||
|
@ -523,7 +531,7 @@ proc beforeNodeProperties(c: Context, e: var Event): bool =
|
|||
else:
|
||||
c.popLevel()
|
||||
return false
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
return false
|
||||
|
||||
proc afterCompactParent(c: Context, e: var Event): bool =
|
||||
|
@ -538,7 +546,7 @@ proc afterCompactParent(c: Context, e: var Event): bool =
|
|||
c.transition(inBlockSeq, c.lex.recentIndentation())
|
||||
c.pushLevel(beforeBlockIndentation)
|
||||
c.pushLevel(afterCompactParent, c.lex.recentIndentation())
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
return true
|
||||
of MapKeyInd:
|
||||
e = startMapEvent(csBlock, c.headerProps, c.headerStart, c.lex.curEndPos)
|
||||
|
@ -546,7 +554,7 @@ proc afterCompactParent(c: Context, e: var Event): bool =
|
|||
c.transition(beforeBlockMapValue, c.lex.recentIndentation())
|
||||
c.pushLevel(beforeBlockIndentation)
|
||||
c.pushLevel(afterCompactParent, c.lex.recentIndentation)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
return true
|
||||
else:
|
||||
c.transition(afterCompactParentProps)
|
||||
|
@ -573,7 +581,7 @@ proc afterCompactParentProps(c: Context, e: var Event): bool =
|
|||
of Alias:
|
||||
e = aliasEvent(c.lex.shortLexeme().Anchor, c.inlineStart, c.lex.curEndPos)
|
||||
let headerEnd = c.lex.curStartPos
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
if c.lex.cur == Token.MapValueInd:
|
||||
c.keyCache.add(move(e))
|
||||
e = startMapEvent(csBlock, defaultProperties, headerEnd, headerEnd)
|
||||
|
@ -588,7 +596,7 @@ proc afterCompactParentProps(c: Context, e: var Event): bool =
|
|||
c.inlineProps = defaultProperties
|
||||
let headerEnd = c.lex.curStartPos
|
||||
c.updateIndentation(c.lex.recentIndentation())
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
if c.lex.cur == Token.MapValueInd:
|
||||
if c.lex.lastScalarWasMultiline():
|
||||
raise c.generateError("Implicit mapping key may not be multiline")
|
||||
|
@ -629,7 +637,7 @@ proc afterBlockParentProps(c: Context, e: var Event): bool =
|
|||
e = scalarEvent(c.lex.evaluated, autoScalarTag(c.inlineProps, c.lex.cur),
|
||||
toStyle(c.lex.cur), c.inlineStart, c.lex.curEndPos)
|
||||
c.inlineProps = defaultProperties
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
if c.lex.cur == Token.MapValueInd:
|
||||
raise c.generateError("Compact notation not allowed after implicit key")
|
||||
c.popLevel()
|
||||
|
@ -650,7 +658,7 @@ proc beforeDocEnd(c: Context, e: var Event): bool =
|
|||
of DocumentEnd:
|
||||
e = endDocEvent(true, c.lex.curStartPos, c.lex.curEndPos)
|
||||
c.transition(beforeDoc)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
resetHandles(c.handles)
|
||||
of StreamEnd:
|
||||
e = endDocEvent(false, c.lex.curStartPos, c.lex.curEndPos)
|
||||
|
@ -668,7 +676,7 @@ proc inBlockSeq(c: Context, e: var Event): bool =
|
|||
raise c.generateError("Invalid indentation: got " & $c.blockIndentation & ", expected " & $c.levels[^1].indentation)
|
||||
case c.lex.cur
|
||||
of SeqItemInd:
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
c.pushLevel(beforeBlockIndentation)
|
||||
c.pushLevel(afterCompactParent, c.blockIndentation)
|
||||
return false
|
||||
|
@ -690,7 +698,7 @@ proc beforeBlockMapKey(c: Context, e: var Event): bool =
|
|||
c.transition(beforeBlockMapValue)
|
||||
c.pushLevel(beforeBlockIndentation)
|
||||
c.pushLevel(afterCompactParent, c.blockIndentation)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
return false
|
||||
of nodePropertyKind:
|
||||
c.transition(atBlockMapKeyProps)
|
||||
|
@ -701,7 +709,7 @@ proc beforeBlockMapKey(c: Context, e: var Event): bool =
|
|||
return false
|
||||
of Alias:
|
||||
e = aliasEvent(c.lex.shortLexeme().Anchor, c.inlineStart, c.lex.curEndPos)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
c.transition(afterImplicitKey)
|
||||
return true
|
||||
of MapValueInd:
|
||||
|
@ -730,14 +738,14 @@ proc atBlockMapKeyProps(c: Context, e: var Event): bool =
|
|||
return true
|
||||
else:
|
||||
raise c.generateError("Unexpected token (expected implicit mapping key): " & $c.lex.cur)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
c.transition(afterImplicitKey)
|
||||
return true
|
||||
|
||||
proc afterImplicitKey(c: Context, e: var Event): bool =
|
||||
if c.lex.cur != Token.MapValueInd:
|
||||
raise c.generateError("Unexpected token (expected ':'): " & $c.lex.cur)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
c.transition(beforeBlockMapKey)
|
||||
c.pushLevel(beforeBlockIndentation)
|
||||
c.pushLevel(afterBlockParent, max(0, c.levels[^2].indentation))
|
||||
|
@ -751,7 +759,7 @@ proc beforeBlockMapValue(c: Context, e: var Event): bool =
|
|||
c.transition(beforeBlockMapKey)
|
||||
c.pushLevel(beforeBlockIndentation)
|
||||
c.pushLevel(afterCompactParent, c.blockIndentation)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
of MapKeyInd, Plain, SingleQuoted, DoubleQuoted, nodePropertyKind:
|
||||
# the value is allowed to be missing after an explicit key
|
||||
e = scalarEvent("", defaultProperties, ssPlain, c.lex.curStartPos, c.lex.curEndPos)
|
||||
|
@ -787,7 +795,7 @@ proc beforeBlockIndentation(c: Context, e: var Event): bool =
|
|||
endBlockNode(e)
|
||||
return true
|
||||
else:
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
return false
|
||||
of StreamEnd, DocumentEnd, DirectivesEnd:
|
||||
c.blockIndentation = 0
|
||||
|
@ -807,7 +815,7 @@ proc beforeFlowItem(c: Context, e: var Event): bool =
|
|||
c.pushLevel(beforeNodeProperties)
|
||||
of Alias:
|
||||
e = aliasEvent(c.lex.shortLexeme().Anchor, c.inlineStart, c.lex.curEndPos)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
c.popLevel()
|
||||
return true
|
||||
else:
|
||||
|
@ -820,22 +828,22 @@ proc beforeFlowItemProps(c: Context, e: var Event): bool =
|
|||
c.pushLevel(beforeNodeProperties)
|
||||
of Alias:
|
||||
e = aliasEvent(c.lex.shortLexeme().Anchor, c.inlineStart, c.lex.curEndPos)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
c.popLevel()
|
||||
of scalarTokenKind:
|
||||
e = scalarEvent(c.lex.evaluated, autoScalarTag(c.inlineProps, c.lex.cur),
|
||||
toStyle(c.lex.cur), c.inlineStart, c.lex.curEndPos)
|
||||
c.inlineProps = defaultProperties
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
c.popLevel()
|
||||
of MapStart:
|
||||
e = startMapEvent(csFlow, c.inlineProps, c.inlineStart, c.lex.curEndPos)
|
||||
c.transition(afterFlowMapSep)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
of SeqStart:
|
||||
e = startSeqEvent(csFlow, c.inlineProps, c.inlineStart, c.lex.curEndPos)
|
||||
c.transition(afterFlowSeqSep)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
of MapEnd, SeqEnd, SeqSep, MapValueInd:
|
||||
e = scalarEvent("", c.inlineProps, ssPlain, c.inlineStart, c.lex.curEndPos)
|
||||
c.popLevel()
|
||||
|
@ -849,7 +857,7 @@ proc afterFlowMapKey(c: Context, e: var Event): bool =
|
|||
of MapValueInd:
|
||||
c.transition(afterFlowMapValue)
|
||||
c.pushLevel(beforeFlowItem)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
return false
|
||||
of SeqSep, MapEnd:
|
||||
e = scalarEvent("", defaultProperties, ssPlain, c.lex.curStartPos, c.lex.curEndPos)
|
||||
|
@ -862,11 +870,11 @@ proc afterFlowMapValue(c: Context, e: var Event): bool =
|
|||
case c.lex.cur
|
||||
of SeqSep:
|
||||
c.transition(afterFlowMapSep)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
return false
|
||||
of MapEnd:
|
||||
e = endMapEvent(c.lex.curStartPos, c.lex.curEndPos)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
c.popLevel()
|
||||
return true
|
||||
of Plain, SingleQuoted, DoubleQuoted, MapKeyInd, Token.Anchor, Alias, MapStart, SeqStart:
|
||||
|
@ -878,11 +886,11 @@ proc afterFlowSeqItem(c: Context, e: var Event): bool =
|
|||
case c.lex.cur
|
||||
of SeqSep:
|
||||
c.transition(afterFlowSeqSep)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
return false
|
||||
of SeqEnd:
|
||||
e = endSeqEvent(c.lex.curStartPos, c.lex.curEndPos)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
c.popLevel()
|
||||
return true
|
||||
of Plain, SingleQuoted, DoubleQuoted, MapKeyInd, Token.Anchor, Alias, MapStart, SeqStart:
|
||||
|
@ -893,10 +901,10 @@ proc afterFlowSeqItem(c: Context, e: var Event): bool =
|
|||
proc afterFlowMapSep(c: Context, e: var Event): bool =
|
||||
case c.lex.cur
|
||||
of MapKeyInd:
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
of MapEnd:
|
||||
e = endMapEvent(c.lex.curStartPos, c.lex.curEndPos)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
c.popLevel()
|
||||
return true
|
||||
of SeqSep:
|
||||
|
@ -911,7 +919,7 @@ proc afterFlowSeqSep(c: Context, e: var Event): bool =
|
|||
case c.lex.cur
|
||||
of SeqSep:
|
||||
e = scalarEvent("", defaultProperties, ssPlain, c.lex.curStartPos, c.lex.curStartPos)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
return true
|
||||
of nodePropertyKind:
|
||||
c.transition(afterFlowSeqSepProps)
|
||||
|
@ -923,7 +931,7 @@ proc afterFlowSeqSep(c: Context, e: var Event): bool =
|
|||
of MapKeyInd:
|
||||
c.transition(afterFlowSeqSepProps)
|
||||
e = startMapEvent(csFlow, defaultProperties, c.lex.curStartPos, c.lex.curEndPos)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
c.transition(afterFlowSeqItem)
|
||||
c.pushLevel(beforePairValue)
|
||||
c.pushLevel(beforeFlowItem)
|
||||
|
@ -935,7 +943,7 @@ proc afterFlowSeqSep(c: Context, e: var Event): bool =
|
|||
return true
|
||||
of SeqEnd:
|
||||
e = endSeqEvent(c.lex.curStartPos, c.lex.curEndPos)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
c.popLevel()
|
||||
return true
|
||||
else:
|
||||
|
@ -951,7 +959,7 @@ proc afterFlowSeqSepProps(c: Context, e: var Event): bool =
|
|||
e = scalarEvent(c.lex.evaluated, autoScalarTag(c.inlineProps, c.lex.cur),
|
||||
toStyle(c.lex.cur), c.inlineStart, c.lex.curEndPos)
|
||||
c.inlineProps = defaultProperties
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
if c.lex.cur == Token.MapValueInd:
|
||||
c.pushLevel(afterImplicitPairStart)
|
||||
if c.caching:
|
||||
|
@ -1003,7 +1011,7 @@ proc beforePairValue(c: Context, e: var Event): bool =
|
|||
if c.lex.cur == Token.MapValueInd:
|
||||
c.transition(afterPairValue)
|
||||
c.pushLevel(beforeFlowItem)
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
return false
|
||||
else:
|
||||
# pair ends here without value
|
||||
|
@ -1012,7 +1020,7 @@ proc beforePairValue(c: Context, e: var Event): bool =
|
|||
return true
|
||||
|
||||
proc afterImplicitPairStart(c: Context, e: var Event): bool =
|
||||
c.lex.next()
|
||||
c.safeNext()
|
||||
c.transition(afterPairValue)
|
||||
c.pushLevel(beforeFlowItem)
|
||||
return false
|
||||
|
|
|
@ -29,12 +29,10 @@ type
|
|||
propertyIndentation: int
|
||||
|
||||
LexerError* = object of ValueError
|
||||
line*, column*: int
|
||||
line*, column*: Positive
|
||||
lineContent*: string
|
||||
|
||||
# temporarily missing .raises: [LexerError]
|
||||
# due to https://github.com/nim-lang/Nim/issues/13905
|
||||
State = proc(lex: var Lexer): bool {.locks: 0, gcSafe, nimcall.}
|
||||
State = proc(lex: var Lexer): bool {.locks: 0, gcSafe, nimcall, raises: [LexerError].}
|
||||
|
||||
Token* {.pure.} = enum
|
||||
YamlDirective, # `%YAML`
|
||||
|
@ -170,10 +168,9 @@ template debug*(message: string) =
|
|||
|
||||
proc generateError(lex: Lexer, message: string):
|
||||
ref LexerError {.raises: [].} =
|
||||
result = newException(LexerError, message)
|
||||
result.line = lex.lineNumber()
|
||||
result.column = lex.columnNumber()
|
||||
result.lineContent = lex.currentLine()
|
||||
result = (ref LexerError)(
|
||||
msg: message, line: lex.lineNumber(), column: lex.columnNumber(),
|
||||
lineContent: lex.currentLine())
|
||||
|
||||
proc startToken(lex: var Lexer) {.inline.} =
|
||||
lex.curStartPos = (line: lex.lineNumber(), column: lex.columnNumber())
|
||||
|
@ -759,7 +756,7 @@ proc fullLexeme*(lex: Lexer): string {.locks: 0.} =
|
|||
proc currentLine*(lex: Lexer): string {.locks: 0.} =
|
||||
return lex.source.getCurrentLine(false)
|
||||
|
||||
proc next*(lex: var Lexer) =
|
||||
proc next*(lex: var Lexer) {.raises: [LexerError].}=
|
||||
while not lex.state(lex): discard
|
||||
debug("lexer -> [" & $lex.curStartPos.line & "," & $lex.curStartPos.column &
|
||||
"-" & $lex.curEndPos.line & "," & $lex.curEndPos.column & "] " & $lex.cur)
|
||||
|
|
|
@ -417,7 +417,7 @@ proc constructObject*(s: var YamlStream, c: ConstructionContext,
|
|||
escape(item.scalarContent))
|
||||
|
||||
proc representObject*(value: Time, ts: TagStyle, c: SerializationContext,
|
||||
tag: Tag) {.raises: [ValueError].} =
|
||||
tag: Tag) {.raises: [].} =
|
||||
let tmp = value.utc()
|
||||
c.put(scalarEvent(tmp.format("yyyy-MM-dd'T'HH:mm:ss'Z'")))
|
||||
|
||||
|
@ -986,7 +986,7 @@ macro genRepresentObject(t: typedesc, value, childTagStyle: typed) =
|
|||
name = $child
|
||||
childAccessor = newDotExpr(value, newIdentNode(name))
|
||||
result.add(quote do:
|
||||
template serializeImpl =
|
||||
template serializeImpl {.used.} =
|
||||
when bool(`isVO`): c.put(startMapEvent())
|
||||
c.put(scalarEvent(`name`, if `childTagStyle` == tsNone:
|
||||
yTagQuestionMark else: yTagNimField, yAnchorNone))
|
||||
|
@ -1397,7 +1397,7 @@ proc load*[K](input: Stream | string, target: var K)
|
|||
elif e.parent of YamlParserError: raise (ref YamlParserError)(e.parent)
|
||||
else: internalError("Unexpected exception: " & $e.parent.name)
|
||||
|
||||
proc loadAs*[K](input: string): K {.raises:
|
||||
proc loadAs*[K](input: Stream | string): K {.raises:
|
||||
[YamlConstructionError, IOError, OSError, YamlParserError].} =
|
||||
## Loads the given YAML input to a value of the type K and returns it
|
||||
load(input, result)
|
||||
|
@ -1480,4 +1480,4 @@ proc dump*[K](value: K, tagStyle: TagStyle = tsRootOnly,
|
|||
if options.style == psJson: asNone else: anchorStyle, handles)
|
||||
try: result = present(events, options)
|
||||
except YamlStreamError:
|
||||
internalError("Unexpected exception: " & $getCurrentException().name)
|
||||
internalError("Unexpected exception: " & $getCurrentException().name)
|
Loading…
Reference in New Issue