Skip to content

Commit 37e74c0

Browse files
authored
Merge pull request #34 from yoheimuta/fix-last-pos-ph2
fix: Set LastPos to the correct Position
2 parents c799c03 + b1f21be commit 37e74c0

File tree

11 files changed

+249
-8
lines changed

11 files changed

+249
-8
lines changed

parser/enum.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,15 @@ func (p *Parser) parseEnumBody() (
169169
}
170170
p.lex.Next()
171171

172+
lastPos := p.lex.Pos
172173
if p.permissive {
173174
// accept a block followed by semicolon. See https://github.com/yoheimuta/go-protoparser/issues/30.
174175
p.lex.ConsumeToken(scanner.TSEMICOLON)
176+
if p.lex.Token == scanner.TSEMICOLON {
177+
lastPos = p.lex.Pos
178+
}
175179
}
176-
return stmts, inlineLeftCurly, p.lex.Pos, nil
180+
return stmts, inlineLeftCurly, lastPos, nil
177181
case scanner.TOPTION:
178182
option, err := p.ParseOption()
179183
if err != nil {

parser/enum_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,28 @@ func TestParser_ParseEnum(t *testing.T) {
486486
},
487487
},
488488
},
489+
{
490+
name: "set LastPos to the correct position when a semicolon doesn't follow the last block",
491+
input: `enum EnumAllowingAlias {
492+
}
493+
`,
494+
permissive: true,
495+
wantEnum: &parser.Enum{
496+
EnumName: "EnumAllowingAlias",
497+
Meta: meta.Meta{
498+
Pos: meta.Position{
499+
Offset: 0,
500+
Line: 1,
501+
Column: 1,
502+
},
503+
LastPos: meta.Position{
504+
Offset: 25,
505+
Line: 2,
506+
Column: 1,
507+
},
508+
},
509+
},
510+
},
489511
}
490512

491513
for _, test := range tests {

parser/extend.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,16 @@ func (p *Parser) parseExtendBody() (
108108
// Parses emptyBody. This spec is not documented, but allowed in general. {
109109
p.lex.Next()
110110
if p.lex.Token == scanner.TRIGHTCURLY {
111+
lastPos := p.lex.Pos
111112
if p.permissive {
112113
// accept a block followed by semicolon. See https://github.com/yoheimuta/go-protoparser/issues/30.
113114
p.lex.ConsumeToken(scanner.TSEMICOLON)
115+
if p.lex.Token == scanner.TSEMICOLON {
116+
lastPos = p.lex.Pos
117+
}
114118
}
115119

116-
return nil, nil, p.lex.Pos, nil
120+
return nil, nil, lastPos, nil
117121
}
118122
p.lex.UnNext()
119123
// }
@@ -141,11 +145,15 @@ func (p *Parser) parseExtendBody() (
141145
}
142146
p.lex.Next()
143147

148+
lastPos := p.lex.Pos
144149
if p.permissive {
145150
// accept a block followed by semicolon. See https://github.com/yoheimuta/go-protoparser/issues/30.
146151
p.lex.ConsumeToken(scanner.TSEMICOLON)
152+
if p.lex.Token == scanner.TSEMICOLON {
153+
lastPos = p.lex.Pos
154+
}
147155
}
148-
return stmts, inlineLeftCurly, p.lex.Pos, nil
156+
return stmts, inlineLeftCurly, lastPos, nil
149157
default:
150158
field, fieldErr := p.ParseField()
151159
if fieldErr == nil {

parser/extend_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,29 @@ extend Foo {
134134
},
135135
},
136136
},
137+
{
138+
name: "set LastPos to the correct position when a semicolon doesn't follow the last block",
139+
input: `
140+
extend Foo {
141+
}
142+
`,
143+
permissive: true,
144+
wantExtend: &parser.Extend{
145+
MessageType: "Foo",
146+
Meta: meta.Meta{
147+
Pos: meta.Position{
148+
Offset: 1,
149+
Line: 2,
150+
Column: 1,
151+
},
152+
LastPos: meta.Position{
153+
Offset: 14,
154+
Line: 3,
155+
Column: 1,
156+
},
157+
},
158+
},
159+
},
137160
}
138161

139162
for _, test := range tests {

parser/groupField_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,30 @@ group Result = 1 {
127127
},
128128
},
129129
},
130+
{
131+
name: "set LastPos to the correct position when a semicolon doesn't follow the last block",
132+
input: `
133+
group Result = 1 {
134+
}
135+
`,
136+
permissive: true,
137+
wantGroupField: &parser.GroupField{
138+
GroupName: "Result",
139+
FieldNumber: "1",
140+
Meta: meta.Meta{
141+
Pos: meta.Position{
142+
Offset: 1,
143+
Line: 2,
144+
Column: 1,
145+
},
146+
LastPos: meta.Position{
147+
Offset: 20,
148+
Line: 3,
149+
Column: 1,
150+
},
151+
},
152+
},
153+
},
130154
}
131155

132156
for _, test := range tests {

parser/message.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,16 @@ func (p *Parser) parseMessageBody() (
110110
// Parses emptyBody. This spec is not documented, but allowed in general. {
111111
p.lex.Next()
112112
if p.lex.Token == scanner.TRIGHTCURLY {
113+
lastPos := p.lex.Pos
113114
if p.permissive {
114115
// accept a block followed by semicolon. See https://github.com/yoheimuta/go-protoparser/issues/30.
115116
p.lex.ConsumeToken(scanner.TSEMICOLON)
117+
if p.lex.Token == scanner.TSEMICOLON {
118+
lastPos = p.lex.Pos
119+
}
116120
}
117121

118-
return nil, nil, p.lex.Pos, nil
122+
return nil, nil, lastPos, nil
119123
}
120124
p.lex.UnNext()
121125
// }
@@ -143,11 +147,15 @@ func (p *Parser) parseMessageBody() (
143147
}
144148
p.lex.Next()
145149

150+
lastPos := p.lex.Pos
146151
if p.permissive {
147152
// accept a block followed by semicolon. See https://github.com/yoheimuta/go-protoparser/issues/30.
148153
p.lex.ConsumeToken(scanner.TSEMICOLON)
154+
if p.lex.Token == scanner.TSEMICOLON {
155+
lastPos = p.lex.Pos
156+
}
149157
}
150-
return stmts, inlineLeftCurly, p.lex.Pos, nil
158+
return stmts, inlineLeftCurly, lastPos, nil
151159
case scanner.TENUM:
152160
enum, err := p.ParseEnum()
153161
if err != nil {

parser/message_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,47 @@ message Outer {
963963
},
964964
},
965965
},
966+
{
967+
name: "set LastPos to the correct position when a semicolon doesn't follow the last block",
968+
input: `
969+
message Outer {
970+
message Inner {}
971+
}
972+
`,
973+
permissive: true,
974+
wantMessage: &parser.Message{
975+
MessageName: "Outer",
976+
MessageBody: []parser.Visitee{
977+
&parser.Message{
978+
MessageName: "Inner",
979+
Meta: meta.Meta{
980+
Pos: meta.Position{
981+
Offset: 19,
982+
Line: 3,
983+
Column: 3,
984+
},
985+
LastPos: meta.Position{
986+
Offset: 34,
987+
Line: 3,
988+
Column: 18,
989+
},
990+
},
991+
},
992+
},
993+
Meta: meta.Meta{
994+
Pos: meta.Position{
995+
Offset: 1,
996+
Line: 2,
997+
Column: 1,
998+
},
999+
LastPos: meta.Position{
1000+
Offset: 36,
1001+
Line: 4,
1002+
Column: 1,
1003+
},
1004+
},
1005+
},
1006+
},
9661007
}
9671008

9681009
for _, test := range tests {

parser/oneof.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,16 +125,20 @@ func (p *Parser) ParseOneof() (*Oneof, error) {
125125
}
126126
}
127127

128+
lastPos := p.lex.Pos
128129
if p.permissive {
129130
// accept a block followed by semicolon. See https://github.com/yoheimuta/go-protoparser/issues/30.
130131
p.lex.ConsumeToken(scanner.TSEMICOLON)
132+
if p.lex.Token == scanner.TSEMICOLON {
133+
lastPos = p.lex.Pos
134+
}
131135
}
132136

133137
return &Oneof{
134138
OneofFields: oneofFields,
135139
OneofName: oneofName,
136140
InlineCommentBehindLeftCurly: inlineLeftCurly,
137-
Meta: meta.NewMetaWithLastPos(startPos, p.lex.Pos),
141+
Meta: meta.NewMetaWithLastPos(startPos, lastPos),
138142
}, nil
139143
}
140144

parser/oneof_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,43 @@ func TestParser_ParseOneof(t *testing.T) {
330330
},
331331
},
332332
},
333+
{
334+
name: "set LastPos to the correct position when a semicolon doesn't follow the last block",
335+
input: `oneof foo {
336+
string name = 4;
337+
}
338+
`,
339+
permissive: true,
340+
wantOneof: &parser.Oneof{
341+
OneofFields: []*parser.OneofField{
342+
{
343+
Type: "string",
344+
FieldName: "name",
345+
FieldNumber: "4",
346+
Meta: meta.Meta{
347+
Pos: meta.Position{
348+
Offset: 16,
349+
Line: 2,
350+
Column: 5,
351+
},
352+
},
353+
},
354+
},
355+
OneofName: "foo",
356+
Meta: meta.Meta{
357+
Pos: meta.Position{
358+
Offset: 0,
359+
Line: 1,
360+
Column: 1,
361+
},
362+
LastPos: meta.Position{
363+
Offset: 33,
364+
Line: 3,
365+
Column: 1,
366+
},
367+
},
368+
},
369+
},
333370
}
334371

335372
for _, test := range tests {

parser/service.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,11 +165,15 @@ func (p *Parser) parseServiceBody() (
165165
}
166166
p.lex.Next()
167167

168+
lastPos := p.lex.Pos
168169
if p.permissive {
169170
// accept a block followed by semicolon. See https://github.com/yoheimuta/go-protoparser/issues/30.
170171
p.lex.ConsumeToken(scanner.TSEMICOLON)
172+
if p.lex.Token == scanner.TSEMICOLON {
173+
lastPos = p.lex.Pos
174+
}
171175
}
172-
return stmts, inlineLeftCurly, p.lex.Pos, nil
176+
return stmts, inlineLeftCurly, lastPos, nil
173177
case scanner.TOPTION:
174178
option, err := p.ParseOption()
175179
if err != nil {
@@ -229,16 +233,21 @@ func (p *Parser) parseRPC() (*RPC, error) {
229233

230234
var opts []*Option
231235
p.lex.Next()
236+
lastPos := p.lex.Pos
232237
switch p.lex.Token {
233238
case scanner.TLEFTCURLY:
234239
p.lex.UnNext()
235240
opts, err = p.parseRPCOptions()
236241
if err != nil {
237242
return nil, err
238243
}
244+
lastPos = p.lex.Pos
239245
if p.permissive {
240246
// accept a block followed by semicolon. See https://github.com/yoheimuta/go-protoparser/issues/30.
241247
p.lex.ConsumeToken(scanner.TSEMICOLON)
248+
if p.lex.Token == scanner.TSEMICOLON {
249+
lastPos = p.lex.Pos
250+
}
242251
}
243252
case scanner.TSEMICOLON:
244253
break
@@ -251,7 +260,7 @@ func (p *Parser) parseRPC() (*RPC, error) {
251260
RPCRequest: rpcRequest,
252261
RPCResponse: rpcResponse,
253262
Options: opts,
254-
Meta: meta.NewMetaWithLastPos(startPos, p.lex.Pos),
263+
Meta: meta.NewMetaWithLastPos(startPos, lastPos),
255264
}, nil
256265
}
257266

0 commit comments

Comments
 (0)