From 034b9b84534be6a0d90a07c559b3a4b9f9181b9d Mon Sep 17 00:00:00 2001 From: Felix Krause Date: Mon, 13 Mar 2023 22:06:07 +0100 Subject: [PATCH] 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 --- flake.lock | 8 +-- flake.nix | 2 +- test/tannotations.nim | 10 ++-- test/tdom.nim | 80 +++++++++++++++--------------- test/tests.nim | 2 +- yaml/dom.nim | 8 ++- yaml/parser.nim | 110 ++++++++++++++++++++++------------------- yaml/private/lex.nim | 15 +++--- yaml/serialization.nim | 8 +-- 9 files changed, 127 insertions(+), 116 deletions(-) diff --git a/flake.lock b/flake.lock index 8317275..37da153 100644 --- a/flake.lock +++ b/flake.lock @@ -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" } diff --git a/flake.nix b/flake.nix index 44d8151..bffc53c 100644 --- a/flake.nix +++ b/flake.nix @@ -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"; }; diff --git a/test/tannotations.nim b/test/tannotations.nim index 7b10b93..6d680ea 100644 --- a/test/tannotations.nim +++ b/test/tannotations.nim @@ -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" diff --git a/test/tdom.nim b/test/tdom.nim index d73da8f..aad98a6 100644 --- a/test/tdom.nim +++ b/test/tdom.nim @@ -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), diff --git a/test/tests.nim b/test/tests.nim index 1a0746d..e58fbc9 100644 --- a/test/tests.nim +++ b/test/tests.nim @@ -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): diff --git a/yaml/dom.nim b/yaml/dom.nim index ae3dbf9..0c9ce9f 100644 --- a/yaml/dom.nim +++ b/yaml/dom.nim @@ -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*. diff --git a/yaml/parser.nim b/yaml/parser.nim index d201dc4..3f2de34 100644 --- a/yaml/parser.nim +++ b/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 diff --git a/yaml/private/lex.nim b/yaml/private/lex.nim index 3855483..aa7d6e5 100644 --- a/yaml/private/lex.nim +++ b/yaml/private/lex.nim @@ -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) diff --git a/yaml/serialization.nim b/yaml/serialization.nim index 7409e5f..dd2a8eb 100644 --- a/yaml/serialization.nim +++ b/yaml/serialization.nim @@ -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) \ No newline at end of file