diff --git a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocLexer.java b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocLexer.java index 546d5df35..f081571d8 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocLexer.java +++ b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocLexer.java @@ -95,10 +95,10 @@ private static String stripJavadocBeginAndEnd(String input) { } private final CharStream input; - private final NestingCounter braceDepth = new NestingCounter(); - private final NestingCounter preDepth = new NestingCounter(); - private final NestingCounter codeDepth = new NestingCounter(); - private final NestingCounter tableDepth = new NestingCounter(); + private final NestingStack braceStack = new NestingStack(); + private final NestingStack preStack = new NestingStack(); + private final NestingStack codeStack = new NestingStack(); + private final NestingStack tableStack = new NestingStack(); private boolean outerInlineTagIsSnippet; private boolean somethingSinceNewline; @@ -162,56 +162,56 @@ private Type consumeToken() throws LexException { somethingSinceNewline = true; if (input.tryConsumeRegex(SNIPPET_TAG_OPEN_PATTERN)) { - if (braceDepth.value() == 0) { - braceDepth.increment(); + if (braceStack.isEmpty()) { + braceStack.push(); outerInlineTagIsSnippet = true; return SNIPPET_BEGIN; } - braceDepth.increment(); + braceStack.push(); return LITERAL; } else if (input.tryConsumeRegex(INLINE_TAG_OPEN_PATTERN)) { - braceDepth.increment(); + braceStack.push(); return LITERAL; } else if (input.tryConsume("{")) { - braceDepth.incrementIfPositive(); + braceStack.incrementIfPositive(); return LITERAL; } else if (input.tryConsume("}")) { - if (outerInlineTagIsSnippet && braceDepth.value() == 1) { - braceDepth.decrementIfPositive(); + if (outerInlineTagIsSnippet && braceStack.total() == 1) { + braceStack.popIfNotEmpty(); outerInlineTagIsSnippet = false; return SNIPPET_END; } - braceDepth.decrementIfPositive(); + braceStack.popIfNotEmpty(); return LITERAL; } // Inside an inline tag, don't do any HTML interpretation. - if (braceDepth.isPositive()) { + if (!braceStack.isEmpty()) { verify(input.tryConsumeRegex(LITERAL_PATTERN)); return LITERAL; } if (input.tryConsumeRegex(PRE_OPEN_PATTERN)) { - preDepth.increment(); + preStack.push(); return preserveExistingFormatting ? LITERAL : PRE_OPEN_TAG; } else if (input.tryConsumeRegex(PRE_CLOSE_PATTERN)) { - preDepth.decrementIfPositive(); + preStack.popIfNotEmpty(); return preserveExistingFormatting() ? LITERAL : PRE_CLOSE_TAG; } if (input.tryConsumeRegex(CODE_OPEN_PATTERN)) { - codeDepth.increment(); + codeStack.push(); return preserveExistingFormatting ? LITERAL : CODE_OPEN_TAG; } else if (input.tryConsumeRegex(CODE_CLOSE_PATTERN)) { - codeDepth.decrementIfPositive(); + codeStack.popIfNotEmpty(); return preserveExistingFormatting() ? LITERAL : CODE_CLOSE_TAG; } if (input.tryConsumeRegex(TABLE_OPEN_PATTERN)) { - tableDepth.increment(); + tableStack.push(); return preserveExistingFormatting ? LITERAL : TABLE_OPEN_TAG; } else if (input.tryConsumeRegex(TABLE_CLOSE_PATTERN)) { - tableDepth.decrementIfPositive(); + tableStack.popIfNotEmpty(); return preserveExistingFormatting() ? LITERAL : TABLE_CLOSE_TAG; } @@ -255,17 +255,17 @@ private Type consumeToken() throws LexException { } private boolean preserveExistingFormatting() { - return preDepth.isPositive() - || tableDepth.isPositive() - || codeDepth.isPositive() + return !preStack.isEmpty() + || !tableStack.isEmpty() + || !codeStack.isEmpty() || outerInlineTagIsSnippet; } private void checkMatchingTags() throws LexException { - if (braceDepth.isPositive() - || preDepth.isPositive() - || tableDepth.isPositive() - || codeDepth.isPositive()) { + if (!braceStack.isEmpty() + || !preStack.isEmpty() + || !tableStack.isEmpty() + || !codeStack.isEmpty()) { throw new LexException(); } } diff --git a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java index 427fcf51d..7f70b76b6 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java @@ -49,9 +49,9 @@ final class JavadocWriter { private boolean continuingListItemOfInnermostList; private boolean continuingFooterTag; - private final NestingCounter continuingListItemCount = new NestingCounter(); - private final NestingCounter continuingListCount = new NestingCounter(); - private final NestingCounter postWriteModifiedContinuingListCount = new NestingCounter(); + private final NestingStack continuingListItemStack = new NestingStack(); + private final NestingStack continuingListStack = new NestingStack(); + private final NestingStack postWriteModifiedContinuingListStack = new NestingStack(); private int remainingOnLine; private boolean atStartOfLine; private RequestedWhitespace requestedWhitespace = NONE; @@ -102,13 +102,13 @@ void writeFooterJavadocTagStart(Token token) { * currently know which of those tags are open. */ continuingListItemOfInnermostList = false; - continuingListItemCount.reset(); - continuingListCount.reset(); + continuingListItemStack.reset(); + continuingListStack.reset(); /* * There's probably no need for this, since its only effect is to disable blank lines in some * cases -- and we're doing that already in the footer. */ - postWriteModifiedContinuingListCount.reset(); + postWriteModifiedContinuingListStack.reset(); if (!wroteAnythingSignificant) { // Javadoc consists solely of tags. This is frowned upon in general but OK for @Overrides. @@ -161,8 +161,8 @@ void writeListOpen(Token token) { writeToken(token); continuingListItemOfInnermostList = false; - continuingListCount.increment(); - postWriteModifiedContinuingListCount.increment(); + continuingListStack.push(2); + postWriteModifiedContinuingListStack.push(); requestNewline(); } @@ -170,10 +170,10 @@ void writeListOpen(Token token) { void writeListClose(Token token) { requestNewline(); - continuingListItemCount.decrementIfPositive(); - continuingListCount.decrementIfPositive(); + continuingListItemStack.popIfNotEmpty(); + continuingListStack.popIfNotEmpty(); writeToken(token); - postWriteModifiedContinuingListCount.decrementIfPositive(); + postWriteModifiedContinuingListStack.popIfNotEmpty(); requestBlankLine(); } @@ -183,11 +183,11 @@ void writeListItemOpen(Token token) { if (continuingListItemOfInnermostList) { continuingListItemOfInnermostList = false; - continuingListItemCount.decrementIfPositive(); + continuingListItemStack.popIfNotEmpty(); } writeToken(token); continuingListItemOfInnermostList = true; - continuingListItemCount.increment(); + continuingListItemStack.push(4); } void writeHeaderOpen(Token token) { @@ -325,7 +325,7 @@ private void writeToken(Token token) { } if (requestedWhitespace == BLANK_LINE - && (postWriteModifiedContinuingListCount.isPositive() || continuingFooterTag)) { + && (!postWriteModifiedContinuingListStack.isEmpty() || continuingFooterTag)) { /* * We don't write blank lines inside lists or footer tags, even in cases where we otherwise * would (e.g., before a
tag). Justification: We don't write blank lines _between_ list
@@ -418,7 +418,7 @@ enum AutoIndent {
}
private int innerIndent() {
- int innerIndent = continuingListItemCount.value() * 4 + continuingListCount.value() * 2;
+ int innerIndent = continuingListItemStack.total() + continuingListStack.total();
if (continuingFooterTag) {
innerIndent += 4;
}
diff --git a/core/src/main/java/com/google/googlejavaformat/java/javadoc/NestingCounter.java b/core/src/main/java/com/google/googlejavaformat/java/javadoc/NestingCounter.java
deleted file mode 100644
index 43e7125c9..000000000
--- a/core/src/main/java/com/google/googlejavaformat/java/javadoc/NestingCounter.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.googlejavaformat.java.javadoc;
-
-/** Mutable integer for tracking the level of nesting. */
-final class NestingCounter {
- private int value;
-
- int value() {
- return value;
- }
-
- void increment() {
- value++;
- }
-
- void incrementIfPositive() {
- if (value > 0) {
- value++;
- }
- }
-
- void decrementIfPositive() {
- if (value > 0) {
- value--;
- }
- }
-
- boolean isPositive() {
- return value > 0;
- }
-
- void reset() {
- value = 0;
- }
-}
diff --git a/core/src/main/java/com/google/googlejavaformat/java/javadoc/NestingStack.java b/core/src/main/java/com/google/googlejavaformat/java/javadoc/NestingStack.java
new file mode 100644
index 000000000..c029428df
--- /dev/null
+++ b/core/src/main/java/com/google/googlejavaformat/java/javadoc/NestingStack.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.googlejavaformat.java.javadoc;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+
+/**
+ * Stack for tracking the level of nesting. In the simplest case, each entry is just the integer 1,
+ * and the stack is effectively a counter. In more complex cases, the entries may depend on context.
+ * For example, if the stack is keeping track of Javadoc lists, the entries represent indentation
+ * levels, and those depend on whether the list is an HTML list or a Markdown list.
+ */
+final class NestingStack {
+ private int total;
+ private final Deque