Skip to content

Commit

Permalink
Simplify handling of newline characters at the end of previous items …
Browse files Browse the repository at this point in the history
…in the parse loop.

PiperOrigin-RevId: 597594817
  • Loading branch information
txtpbfmt-copybara-robot committed Jan 11, 2024
1 parent 084445f commit 321f227
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 8 deletions.
20 changes: 12 additions & 8 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -567,24 +567,23 @@ func (p *parser) parse(isRoot bool) (result []*ast.Node, endPos ast.Position, er
return nil, ast.Position{}, err
}

startPos := p.position()
if p.nextInputIs('\n') {
// p.parse is often invoked with the index pointing at the
// newline character after the previous item.
// We should still report that this item starts in the next line.
startPos.Byte++
startPos.Line++
startPos.Column = 1
p.consume('\n')
}
startPos := p.position()

// Read PreComments.
comments, blankLines := p.skipWhiteSpaceAndReadComments(true /* multiLine */)

// Handle blank lines.
if blankLines > 1 {
if blankLines > 0 {
if p.config.infoLevel() {
p.config.infof("blankLines: %v", blankLines)
}
// Here we collapse the leading blank lines into one blank line.
comments = append([]string{""}, comments...)
}

Expand Down Expand Up @@ -824,15 +823,20 @@ func (p *parser) readContinuousBlocksOfComments() []string {
// skipWhiteSpaceAndReadComments has multiple cases:
// - (1) reading a block of comments followed by a blank line
// - (2) reading a block of comments followed by non-blank content
// - (3) reading the inline comments between the current char and the end of the
// current line
// - (3) reading the inline comments between the current char and the end of
// the current line
//
// In both cases (1) and (2), there can also be blank lines before the comment
// starts.
//
// Lines of comments and number of blank lines will be returned.
// Lines of comments and number of blank lines before the comment will be
// returned. If there is no comment, the returned slice will be empty.
func (p *parser) skipWhiteSpaceAndReadComments(multiLine bool) ([]string, int) {
i := p.index
var foundComment, insideComment bool
commentBegin := 0
var comments []string
// Number of blanks lines *before* the comment (if any) starts.
blankLines := 0
for ; i < p.length; i++ {
if p.in[i] == '#' && !insideComment {
Expand Down
78 changes: 78 additions & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1126,6 +1126,57 @@ presubmit: {
prohibited_regexp: "UnsafeFunction"
}
}
`}, {
name: "blank lines before comment blocks are collapsed to one",
in: `# txtpbfmt: sort_repeated_fields_by_content
presubmit: {
check_contents: {
# Should go after ADD.
# And the empty lines above this are collapsed into one blank line.
operation: EDIT
operation: ADD
operation: REMOVE
}
}
`,
out: `# txtpbfmt: sort_repeated_fields_by_content
presubmit: {
check_contents: {
operation: ADD
# Should go after ADD.
# And the empty lines above this are collapsed into one blank line.
operation: EDIT
operation: REMOVE
}
}
`}, {
name: "blank lines before comment blocks are collapsed to one",
in: `# txtpbfmt: sort_repeated_fields_by_content
presubmit: {
check_contents: {
# This comment is a separate node and does not move when the fields are sorted.
operation: EDIT
operation: ADD
}
}
`,
out: `# txtpbfmt: sort_repeated_fields_by_content
presubmit: {
check_contents: {
# This comment is a separate node and does not move when the fields are sorted.
operation: ADD
operation: EDIT
}
}
`}, {
name: "sort by subfield values",
in: `# txtpbfmt: sort_repeated_fields_by_subfield=operation.name
Expand Down Expand Up @@ -1318,6 +1369,33 @@ field: "a"
field: "b"
message: { id: "a" }
message: { id: "b" }
`}, {
name: "detached comment creates a new group for sorting",
in: `# txtpbfmt: sort_repeated_fields_by_content
# field c
field: "c"
# field a
field: "a"
# new group - the fields below don't get sorted with the fields above
# field b
field: "b"
`,
out: `# txtpbfmt: sort_repeated_fields_by_content
# field a
field: "a"
# field c
field: "c"
# new group - the fields below don't get sorted with the fields above
# field b
field: "b"
`}, {
name: "trailing comma / semicolon",
in: `dict: {
Expand Down

0 comments on commit 321f227

Please sign in to comment.