From 33377907ec1dde7f9c329e41d0adcb2cda336395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw=20Barzowski?= Date: Fri, 29 Sep 2017 17:45:25 -0400 Subject: [PATCH] Allow all kinds of string literals as object field names --- parser/parser.go | 101 +++++++++----------- testdata/object_various_field_types.golden | 9 ++ testdata/object_various_field_types.jsonnet | 13 +++ 3 files changed, 68 insertions(+), 55 deletions(-) create mode 100644 testdata/object_various_field_types.golden create mode 100644 testdata/object_various_field_types.jsonnet diff --git a/parser/parser.go b/parser/parser.go index e98337f..78dbc40 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -372,7 +372,8 @@ func (p *parser) parseObjectRemainder(tok *token) (ast.Node, *token, error) { first = false switch next.kind { - case tokenBracketL, tokenIdentifier, tokenStringDouble, tokenStringSingle, tokenStringBlock: + case tokenBracketL, tokenIdentifier, tokenStringDouble, tokenStringSingle, + tokenStringBlock, tokenVerbatimStringDouble, tokenVerbatimStringSingle: var kind ast.ObjectFieldKind var expr1 ast.Node var id *ast.Identifier @@ -380,30 +381,10 @@ func (p *parser) parseObjectRemainder(tok *token) (ast.Node, *token, error) { case tokenIdentifier: kind = ast.ObjectFieldID id = (*ast.Identifier)(&next.data) - case tokenStringDouble: + case tokenStringDouble, tokenStringSingle, + tokenStringBlock, tokenVerbatimStringDouble, tokenVerbatimStringSingle: kind = ast.ObjectFieldStr - expr1 = &ast.LiteralString{ - NodeBase: ast.NewNodeBaseLoc(next.loc), - Value: next.data, - Kind: ast.StringDouble, - } - case tokenStringSingle: - kind = ast.ObjectFieldStr - expr1 = &ast.LiteralString{ - NodeBase: ast.NewNodeBaseLoc(next.loc), - Value: next.data, - Kind: ast.StringSingle, - } - case tokenStringBlock: - kind = ast.ObjectFieldStr - expr1 = &ast.LiteralString{ - NodeBase: ast.NewNodeBaseLoc(next.loc), - Value: next.data, - Kind: ast.StringBlock, - BlockIndent: next.stringBlockIndent, - } - // TODO(sbarzowski) are verbatim string literals allowed here? - // if so, maybe it's time we extracted string literal creation somewhere... + expr1 = tokenStringToAst(next) default: kind = ast.ObjectFieldExpr var err error @@ -680,6 +661,44 @@ func (p *parser) parseArray(tok *token) (ast.Node, error) { }, nil } +func tokenStringToAst(tok *token) *ast.LiteralString { + switch tok.kind { + case tokenStringSingle: + return &ast.LiteralString{ + NodeBase: ast.NewNodeBaseLoc(tok.loc), + Value: tok.data, + Kind: ast.StringSingle, + } + case tokenStringDouble: + return &ast.LiteralString{ + NodeBase: ast.NewNodeBaseLoc(tok.loc), + Value: tok.data, + Kind: ast.StringDouble, + } + case tokenStringBlock: + return &ast.LiteralString{ + NodeBase: ast.NewNodeBaseLoc(tok.loc), + Value: tok.data, + Kind: ast.StringBlock, + BlockIndent: tok.stringBlockIndent, + } + case tokenVerbatimStringDouble: + return &ast.LiteralString{ + NodeBase: ast.NewNodeBaseLoc(tok.loc), + Value: tok.data, + Kind: ast.VerbatimStringDouble, + } + case tokenVerbatimStringSingle: + return &ast.LiteralString{ + NodeBase: ast.NewNodeBaseLoc(tok.loc), + Value: tok.data, + Kind: ast.VerbatimStringSingle, + } + default: + panic(fmt.Sprintf("Not a string token %#+v", tok)) + } +} + func (p *parser) parseTerminal() (ast.Node, error) { tok := p.pop() switch tok.kind { @@ -722,37 +741,9 @@ func (p *parser) parseTerminal() (ast.Node, error) { Value: num, OriginalString: tok.data, }, nil - case tokenStringSingle: - return &ast.LiteralString{ - NodeBase: ast.NewNodeBaseLoc(tok.loc), - Value: tok.data, - Kind: ast.StringSingle, - }, nil - case tokenStringDouble: - return &ast.LiteralString{ - NodeBase: ast.NewNodeBaseLoc(tok.loc), - Value: tok.data, - Kind: ast.StringDouble, - }, nil - case tokenStringBlock: - return &ast.LiteralString{ - NodeBase: ast.NewNodeBaseLoc(tok.loc), - Value: tok.data, - Kind: ast.StringBlock, - BlockIndent: tok.stringBlockIndent, - }, nil - case tokenVerbatimStringDouble: - return &ast.LiteralString{ - NodeBase: ast.NewNodeBaseLoc(tok.loc), - Value: tok.data, - Kind: ast.VerbatimStringDouble, - }, nil - case tokenVerbatimStringSingle: - return &ast.LiteralString{ - NodeBase: ast.NewNodeBaseLoc(tok.loc), - Value: tok.data, - Kind: ast.VerbatimStringSingle, - }, nil + case tokenStringDouble, tokenStringSingle, + tokenStringBlock, tokenVerbatimStringDouble, tokenVerbatimStringSingle: + return tokenStringToAst(tok), nil case tokenFalse: return &ast.LiteralBoolean{ NodeBase: ast.NewNodeBaseLoc(tok.loc), diff --git a/testdata/object_various_field_types.golden b/testdata/object_various_field_types.golden new file mode 100644 index 0000000..caf46b8 --- /dev/null +++ b/testdata/object_various_field_types.golden @@ -0,0 +1,9 @@ +{ + "expr, as complex as you want": true, + "identifier": true, + "str_block \\n\n": true, + "str_double ' \n": true, + "str_single \" \n": true, + "str_verbatim_double \" '' \\n": true, + "str_verbatim_single \"\" ' \\n": true +} diff --git a/testdata/object_various_field_types.jsonnet b/testdata/object_various_field_types.jsonnet new file mode 100644 index 0000000..acfe464 --- /dev/null +++ b/testdata/object_various_field_types.jsonnet @@ -0,0 +1,13 @@ +{ + identifier: true, + "str_double ' \n": true, + 'str_single " \n': true, + ||| + str_block \n + |||: true, + @"str_verbatim_double "" '' \n": true, + @'str_verbatim_single "" '' \n': true, + ["expr, " + "as complex as you want"]: true, + local local_field = true, + assert true +}