From 2fa54d32bfb46982f2462d7e60531432d27c4190 Mon Sep 17 00:00:00 2001 From: Ernest Micklei <> Date: Tue, 2 Jan 2018 22:44:47 +0100 Subject: [PATCH] fix issue #42 : inline comment on options + RPC.Options -> RPC.Elements --- option.go | 1 + option_test.go | 24 ++++++++++++++++++++++++ service.go | 29 +++++++++++++++++++++++++---- service_test.go | 17 ++++++++++++++--- 4 files changed, 64 insertions(+), 7 deletions(-) diff --git a/option.go b/option.go index 31ef9d8..a7cc470 100644 --- a/option.go +++ b/option.go @@ -169,6 +169,7 @@ func (o *Option) parseAggregate(p *Parser) error { continue } if tSEMICOLON == tok { + p.nextPut(pos, tok, lit) // allow for inline comment parsing return nil } if tCOMMA == tok { diff --git a/option_test.go b/option_test.go index 1c36772..b7f175c 100644 --- a/option_test.go +++ b/option_test.go @@ -189,3 +189,27 @@ message Bar { t.Fatalf("got [%v] want [%v]", got, want) } } + +func TestNonPrimitiveOptionComment(t *testing.T) { + proto := ` +// comment +option Help = { string_field: "value" }; // inline` + p := newParserOn(proto) + pr, err := p.Parse() + if err != nil { + t.Fatal(err) + } + o := pr.Elements[0].(*Option) + if got, want := o.Comment != nil, true; got != want { + t.Fatalf("got [%v] want [%v]", got, want) + } + if got, want := o.Comment.Lines[0], " comment"; got != want { + t.Fatalf("got [%v] want [%v]", got, want) + } + if got, want := o.InlineComment != nil, true; got != want { + t.Fatalf("got [%v] want [%v]", got, want) + } + if got, want := o.InlineComment.Lines[0], " inline"; got != want { + t.Fatalf("got [%v] want [%v]", got, want) + } +} diff --git a/service.go b/service.go index 218a27d..60a095e 100644 --- a/service.go +++ b/service.go @@ -112,7 +112,7 @@ type RPC struct { StreamsRequest bool ReturnsType string StreamsReturns bool - Options []*Option + Elements []Visitee InlineComment *Comment } @@ -188,8 +188,14 @@ func (r *RPC) parse(p *Parser) error { if tRIGHTCURLY == tok { break } - if tCOMMENT == tok { - // TODO put comment in the next option + if isComment(lit) { + if com := mergeOrReturnComment(r.elements(), lit, pos); com != nil { // not merged? + r.addElement(com) + continue + } + } + if tSEMICOLON == tok { + maybeScanInlineComment(p, r) continue } if tOPTION != tok { @@ -200,8 +206,23 @@ func (r *RPC) parse(p *Parser) error { if err := o.parse(p); err != nil { return err } - r.Options = append(r.Options, o) + r.Elements = append(r.Elements, o) } } return nil } + +// addElement is part of elementContainer +func (r *RPC) addElement(v Visitee) { + r.Elements = append(r.Elements, v) +} + +// elements is part of elementContainer +func (r *RPC) elements() []Visitee { + return r.Elements +} + +func (r *RPC) takeLastComment() (last *Comment) { + last, r.Elements = takeLastComment(r.Elements) + return +} diff --git a/service_test.go b/service_test.go index 8836050..37df3b5 100644 --- a/service_test.go +++ b/service_test.go @@ -67,10 +67,11 @@ func TestRPCWithOptionAggregateSyntax(t *testing.T) { proto := `service AccountService { // CreateAccount rpc CreateAccount (CreateAccount) returns (ServiceFault){ + // test_ident option (test_ident) = { test: "test" test2:"test2" - }; + }; // inline test_ident } }` pr, err := newParserOn(proto).Parse() @@ -82,13 +83,23 @@ func TestRPCWithOptionAggregateSyntax(t *testing.T) { t.Fatalf("got [%v] want [%v]", got, want) } rpc1 := srv.Elements[0].(*RPC) - if got, want := len(rpc1.Options), 1; got != want { + if got, want := len(rpc1.Elements), 2; got != want { t.Errorf("got [%v] want [%v]", got, want) } - opt := rpc1.Options[0] + com := rpc1.Elements[0].(*Comment) + if got, want := com.Message(), " test_ident"; got != want { + t.Errorf("got [%v] want [%v]", got, want) + } + opt := rpc1.Elements[1].(*Option) if got, want := opt.Name, "(test_ident)"; got != want { t.Errorf("got [%v] want [%v]", got, want) } + if got, want := opt.InlineComment != nil, true; got != want { + t.Fatalf("got [%v] want [%v]", got, want) + } + if got, want := opt.InlineComment.Message(), " inline test_ident"; got != want { + t.Errorf("got [%v] want [%v]", got, want) + } if got, want := len(opt.AggregatedConstants), 2; got != want { t.Fatalf("got [%v] want [%v]", got, want) }