Skip to content

Commit 142c392

Browse files
eamonnmcmanusgoogle-java-format Team
authored andcommitted
Change NestingCounter into NestingStack.
Although most uses will effectively be an expensive counter, with a stack where every element is `Integer.valueOf(1)`, the introduction of Markdown support will mean some uses where that is not the case. For example, the continuing indentation of list items will depend on whether they are HTML lists or Markdown lists, and for Markdown lists it will further depend on the list type. For now, implement the indentation of `<ul>` (etc) and `<li>` using the stack rather than multiplications. PiperOrigin-RevId: 893521393
1 parent 742e4f3 commit 142c392

File tree

4 files changed

+104
-89
lines changed

4 files changed

+104
-89
lines changed

core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocLexer.java

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,10 @@ private static String stripJavadocBeginAndEnd(String input) {
9595
}
9696

9797
private final CharStream input;
98-
private final NestingCounter braceDepth = new NestingCounter();
99-
private final NestingCounter preDepth = new NestingCounter();
100-
private final NestingCounter codeDepth = new NestingCounter();
101-
private final NestingCounter tableDepth = new NestingCounter();
98+
private final NestingStack braceStack = new NestingStack();
99+
private final NestingStack preStack = new NestingStack();
100+
private final NestingStack codeStack = new NestingStack();
101+
private final NestingStack tableStack = new NestingStack();
102102
private boolean outerInlineTagIsSnippet;
103103
private boolean somethingSinceNewline;
104104

@@ -162,56 +162,56 @@ private Type consumeToken() throws LexException {
162162
somethingSinceNewline = true;
163163

164164
if (input.tryConsumeRegex(SNIPPET_TAG_OPEN_PATTERN)) {
165-
if (braceDepth.value() == 0) {
166-
braceDepth.increment();
165+
if (braceStack.isEmpty()) {
166+
braceStack.push();
167167
outerInlineTagIsSnippet = true;
168168
return SNIPPET_BEGIN;
169169
}
170-
braceDepth.increment();
170+
braceStack.push();
171171
return LITERAL;
172172
} else if (input.tryConsumeRegex(INLINE_TAG_OPEN_PATTERN)) {
173-
braceDepth.increment();
173+
braceStack.push();
174174
return LITERAL;
175175
} else if (input.tryConsume("{")) {
176-
braceDepth.incrementIfPositive();
176+
braceStack.incrementIfPositive();
177177
return LITERAL;
178178
} else if (input.tryConsume("}")) {
179-
if (outerInlineTagIsSnippet && braceDepth.value() == 1) {
180-
braceDepth.decrementIfPositive();
179+
if (outerInlineTagIsSnippet && braceStack.total() == 1) {
180+
braceStack.popIfNotEmpty();
181181
outerInlineTagIsSnippet = false;
182182
return SNIPPET_END;
183183
}
184-
braceDepth.decrementIfPositive();
184+
braceStack.popIfNotEmpty();
185185
return LITERAL;
186186
}
187187

188188
// Inside an inline tag, don't do any HTML interpretation.
189-
if (braceDepth.isPositive()) {
189+
if (!braceStack.isEmpty()) {
190190
verify(input.tryConsumeRegex(LITERAL_PATTERN));
191191
return LITERAL;
192192
}
193193

194194
if (input.tryConsumeRegex(PRE_OPEN_PATTERN)) {
195-
preDepth.increment();
195+
preStack.push();
196196
return preserveExistingFormatting ? LITERAL : PRE_OPEN_TAG;
197197
} else if (input.tryConsumeRegex(PRE_CLOSE_PATTERN)) {
198-
preDepth.decrementIfPositive();
198+
preStack.popIfNotEmpty();
199199
return preserveExistingFormatting() ? LITERAL : PRE_CLOSE_TAG;
200200
}
201201

202202
if (input.tryConsumeRegex(CODE_OPEN_PATTERN)) {
203-
codeDepth.increment();
203+
codeStack.push();
204204
return preserveExistingFormatting ? LITERAL : CODE_OPEN_TAG;
205205
} else if (input.tryConsumeRegex(CODE_CLOSE_PATTERN)) {
206-
codeDepth.decrementIfPositive();
206+
codeStack.popIfNotEmpty();
207207
return preserveExistingFormatting() ? LITERAL : CODE_CLOSE_TAG;
208208
}
209209

210210
if (input.tryConsumeRegex(TABLE_OPEN_PATTERN)) {
211-
tableDepth.increment();
211+
tableStack.push();
212212
return preserveExistingFormatting ? LITERAL : TABLE_OPEN_TAG;
213213
} else if (input.tryConsumeRegex(TABLE_CLOSE_PATTERN)) {
214-
tableDepth.decrementIfPositive();
214+
tableStack.popIfNotEmpty();
215215
return preserveExistingFormatting() ? LITERAL : TABLE_CLOSE_TAG;
216216
}
217217

@@ -255,17 +255,17 @@ private Type consumeToken() throws LexException {
255255
}
256256

257257
private boolean preserveExistingFormatting() {
258-
return preDepth.isPositive()
259-
|| tableDepth.isPositive()
260-
|| codeDepth.isPositive()
258+
return !preStack.isEmpty()
259+
|| !tableStack.isEmpty()
260+
|| !codeStack.isEmpty()
261261
|| outerInlineTagIsSnippet;
262262
}
263263

264264
private void checkMatchingTags() throws LexException {
265-
if (braceDepth.isPositive()
266-
|| preDepth.isPositive()
267-
|| tableDepth.isPositive()
268-
|| codeDepth.isPositive()) {
265+
if (!braceStack.isEmpty()
266+
|| !preStack.isEmpty()
267+
|| !tableStack.isEmpty()
268+
|| !codeStack.isEmpty()) {
269269
throw new LexException();
270270
}
271271
}

core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ final class JavadocWriter {
4949
private boolean continuingListItemOfInnermostList;
5050

5151
private boolean continuingFooterTag;
52-
private final NestingCounter continuingListItemCount = new NestingCounter();
53-
private final NestingCounter continuingListCount = new NestingCounter();
54-
private final NestingCounter postWriteModifiedContinuingListCount = new NestingCounter();
52+
private final NestingStack continuingListItemStack = new NestingStack();
53+
private final NestingStack continuingListStack = new NestingStack();
54+
private final NestingStack postWriteModifiedContinuingListStack = new NestingStack();
5555
private int remainingOnLine;
5656
private boolean atStartOfLine;
5757
private RequestedWhitespace requestedWhitespace = NONE;
@@ -102,13 +102,13 @@ void writeFooterJavadocTagStart(Token token) {
102102
* currently know which of those tags are open.
103103
*/
104104
continuingListItemOfInnermostList = false;
105-
continuingListItemCount.reset();
106-
continuingListCount.reset();
105+
continuingListItemStack.reset();
106+
continuingListStack.reset();
107107
/*
108108
* There's probably no need for this, since its only effect is to disable blank lines in some
109109
* cases -- and we're doing that already in the footer.
110110
*/
111-
postWriteModifiedContinuingListCount.reset();
111+
postWriteModifiedContinuingListStack.reset();
112112

113113
if (!wroteAnythingSignificant) {
114114
// Javadoc consists solely of tags. This is frowned upon in general but OK for @Overrides.
@@ -161,19 +161,19 @@ void writeListOpen(Token token) {
161161

162162
writeToken(token);
163163
continuingListItemOfInnermostList = false;
164-
continuingListCount.increment();
165-
postWriteModifiedContinuingListCount.increment();
164+
continuingListStack.push(2);
165+
postWriteModifiedContinuingListStack.push();
166166

167167
requestNewline();
168168
}
169169

170170
void writeListClose(Token token) {
171171
requestNewline();
172172

173-
continuingListItemCount.decrementIfPositive();
174-
continuingListCount.decrementIfPositive();
173+
continuingListItemStack.popIfNotEmpty();
174+
continuingListStack.popIfNotEmpty();
175175
writeToken(token);
176-
postWriteModifiedContinuingListCount.decrementIfPositive();
176+
postWriteModifiedContinuingListStack.popIfNotEmpty();
177177

178178
requestBlankLine();
179179
}
@@ -183,11 +183,11 @@ void writeListItemOpen(Token token) {
183183

184184
if (continuingListItemOfInnermostList) {
185185
continuingListItemOfInnermostList = false;
186-
continuingListItemCount.decrementIfPositive();
186+
continuingListItemStack.popIfNotEmpty();
187187
}
188188
writeToken(token);
189189
continuingListItemOfInnermostList = true;
190-
continuingListItemCount.increment();
190+
continuingListItemStack.push(4);
191191
}
192192

193193
void writeHeaderOpen(Token token) {
@@ -325,7 +325,7 @@ private void writeToken(Token token) {
325325
}
326326

327327
if (requestedWhitespace == BLANK_LINE
328-
&& (postWriteModifiedContinuingListCount.isPositive() || continuingFooterTag)) {
328+
&& (!postWriteModifiedContinuingListStack.isEmpty() || continuingFooterTag)) {
329329
/*
330330
* We don't write blank lines inside lists or footer tags, even in cases where we otherwise
331331
* would (e.g., before a <p> tag). Justification: We don't write blank lines _between_ list
@@ -418,7 +418,7 @@ enum AutoIndent {
418418
}
419419

420420
private int innerIndent() {
421-
int innerIndent = continuingListItemCount.value() * 4 + continuingListCount.value() * 2;
421+
int innerIndent = continuingListItemStack.total() + continuingListStack.total();
422422
if (continuingFooterTag) {
423423
innerIndent += 4;
424424
}

core/src/main/java/com/google/googlejavaformat/java/javadoc/NestingCounter.java

Lines changed: 0 additions & 48 deletions
This file was deleted.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright 2016 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5+
* in compliance with the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License
10+
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11+
* or implied. See the License for the specific language governing permissions and limitations under
12+
* the License.
13+
*/
14+
15+
package com.google.googlejavaformat.java.javadoc;
16+
17+
import java.util.ArrayDeque;
18+
import java.util.Deque;
19+
20+
/**
21+
* Stack for tracking the level of nesting. In the simplest case, each entry is just the integer 1,
22+
* and the stack is effectively a counter. In more complex cases, the entries may depend on context.
23+
* For example, if the stack is keeping track of Javadoc lists, the entries represent indentation
24+
* levels, and those depend on whether the list is an HTML list or a Markdown list.
25+
*/
26+
final class NestingStack {
27+
private int total;
28+
private final Deque<Integer> stack = new ArrayDeque<>();
29+
30+
int total() {
31+
return total;
32+
}
33+
34+
void push() {
35+
push(1);
36+
}
37+
38+
void push(int value) {
39+
stack.push(value);
40+
total += value;
41+
}
42+
43+
void incrementIfPositive() {
44+
if (total > 0) {
45+
push();
46+
}
47+
}
48+
49+
void popIfNotEmpty() {
50+
if (!isEmpty()) {
51+
total -= stack.pop();
52+
}
53+
}
54+
55+
boolean isEmpty() {
56+
return stack.isEmpty();
57+
}
58+
59+
void reset() {
60+
total = 0;
61+
stack.clear();
62+
}
63+
}

0 commit comments

Comments
 (0)