Skip to content

Commit 2c09b93

Browse files
committed
Support optional javadoc formatting using eclipse
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=117850827
1 parent eb00300 commit 2c09b93

File tree

7 files changed

+383
-39
lines changed

7 files changed

+383
-39
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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;
16+
17+
import com.google.common.collect.ImmutableMap;
18+
19+
import org.eclipse.jdt.core.JavaCore;
20+
import org.eclipse.jdt.core.formatter.CodeFormatter;
21+
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
22+
import org.eclipse.jdt.internal.formatter.DefaultCodeFormatter;
23+
import org.eclipse.jdt.internal.formatter.DefaultCodeFormatterOptions;
24+
import org.eclipse.jface.text.BadLocationException;
25+
import org.eclipse.jface.text.Document;
26+
import org.eclipse.text.edits.TextEdit;
27+
28+
/** Format javadoc comments using eclipse's formatter, for now. */
29+
public class EclipseJavadocFormatter {
30+
31+
static String formatJavadoc(String input, int indent, JavaFormatterOptions options) {
32+
33+
ImmutableMap.Builder<String, String> optionBuilder = ImmutableMap.<String, String>builder();
34+
optionBuilder.put(
35+
DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_JAVADOC_COMMENT, "true");
36+
optionBuilder.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE);
37+
optionBuilder.put(
38+
DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE,
39+
Integer.toString(options.indentationMultiplier()));
40+
optionBuilder.put(
41+
DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH,
42+
Integer.toString(options.maxLineLength() - indent));
43+
optionBuilder.put(
44+
DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT,
45+
Integer.toString(options.maxLineLength()));
46+
optionBuilder.put(
47+
DefaultCodeFormatterConstants.FORMATTER_COMMENT_INDENT_PARAMETER_DESCRIPTION,
48+
DefaultCodeFormatterConstants.FALSE);
49+
optionBuilder.put(
50+
DefaultCodeFormatterConstants.FORMATTER_COMMENT_INSERT_NEW_LINE_FOR_PARAMETER,
51+
JavaCore.DO_NOT_INSERT);
52+
optionBuilder.put(
53+
DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_JAVADOC_COMMENT,
54+
DefaultCodeFormatterConstants.FALSE);
55+
optionBuilder.put(
56+
DefaultCodeFormatterConstants.FORMATTER_JOIN_LINES_IN_COMMENTS,
57+
DefaultCodeFormatterConstants.TRUE);
58+
optionBuilder.put(
59+
DefaultCodeFormatterConstants.FORMATTER_JOIN_WRAPPED_LINES,
60+
DefaultCodeFormatterConstants.TRUE);
61+
// Disable indenting root tags for now since it indents more than 4 spaces
62+
optionBuilder.put(
63+
DefaultCodeFormatterConstants.FORMATTER_COMMENT_INDENT_ROOT_TAGS,
64+
DefaultCodeFormatterConstants.FALSE);
65+
optionBuilder.put(
66+
DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_SOURCE,
67+
DefaultCodeFormatterConstants.FALSE);
68+
optionBuilder.put(JavaCore.COMPILER_COMPLIANCE, "1.8");
69+
optionBuilder.put(JavaCore.COMPILER_SOURCE, "1.8");
70+
optionBuilder.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, "1.8");
71+
DefaultCodeFormatter codeFormatter =
72+
new DefaultCodeFormatter(new DefaultCodeFormatterOptions(optionBuilder.build()));
73+
74+
TextEdit edit =
75+
codeFormatter.format(
76+
CodeFormatter.K_JAVA_DOC,
77+
input,
78+
/*offset*/ 0,
79+
input.length(),
80+
// eclipse doesn't indent comments reliably, so always request no indent and fix it
81+
// up later in JavaCommentsHelper
82+
/*indent*/ 0,
83+
/*lineSeparator*/ null);
84+
if (edit == null) {
85+
throw new RuntimeException("error formatting javadoc");
86+
}
87+
Document document = new Document(input);
88+
try {
89+
edit.apply(document);
90+
} catch (BadLocationException e) {
91+
throw new RuntimeException("error formatting javadoc", e);
92+
}
93+
return document.get();
94+
}
95+
}

core/src/main/java/com/google/googlejavaformat/java/FormatFileCallable.java

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.google.common.collect.TreeRangeSet;
2323
import com.google.common.io.CharStreams;
2424
import com.google.googlejavaformat.FormatterDiagnostic;
25+
import com.google.googlejavaformat.java.JavaFormatterOptions.SortImports;
2526

2627
import java.io.BufferedOutputStream;
2728
import java.io.File;
@@ -48,18 +49,16 @@
4849
class FormatFileCallable implements Callable<Boolean> {
4950
private final FileToFormat fileToFormat;
5051
private final Object outputLock;
51-
private final int indentMultiplier;
52+
private final JavaFormatterOptions options;
5253
private final boolean inPlace;
53-
private final SortImports sortImports;
5454
private final PrintWriter outWriter;
5555
private final PrintWriter errWriter;
5656

5757
FormatFileCallable(
5858
FileToFormat fileToFormat,
5959
Object outputLock,
60-
int indentMultiplier,
60+
JavaFormatterOptions options,
6161
boolean inPlace,
62-
SortImports sortImports,
6362
PrintWriter outWriter,
6463
PrintWriter errWriter) {
6564
Preconditions.checkArgument(
@@ -68,19 +67,12 @@ class FormatFileCallable implements Callable<Boolean> {
6867

6968
this.fileToFormat = Preconditions.checkNotNull(fileToFormat);
7069
this.outputLock = Preconditions.checkNotNull(outputLock);
71-
this.indentMultiplier = indentMultiplier;
70+
this.options = options;
7271
this.inPlace = inPlace;
73-
this.sortImports = sortImports;
7472
this.outWriter = Preconditions.checkNotNull(outWriter);
7573
this.errWriter = Preconditions.checkNotNull(errWriter);
7674
}
7775

78-
enum SortImports {
79-
NO,
80-
ONLY,
81-
ALSO
82-
}
83-
8476
/**
8577
* Formats a file and returns whether the operation succeeded.
8678
*/
@@ -91,13 +83,13 @@ public Boolean call() {
9183
return false;
9284
}
9385

94-
if (sortImports != SortImports.NO) {
86+
if (options.sortImports() != SortImports.NO) {
9587
String reordered = reorderImports(inputString);
9688
if (reordered == null) {
9789
return false;
9890
}
9991

100-
if (sortImports == SortImports.ONLY) {
92+
if (options.sortImports() == SortImports.ONLY) {
10193
if (reordered.equals(inputString)) {
10294
return true;
10395
}
@@ -138,9 +130,9 @@ public Boolean call() {
138130
}
139131
}
140132

141-
final JavaOutput javaOutput = new JavaOutput(javaInput, new JavaCommentsHelper());
133+
final JavaOutput javaOutput = new JavaOutput(javaInput, new JavaCommentsHelper(options));
142134
List<FormatterDiagnostic> errors = new ArrayList<>();
143-
Formatter.format(javaInput, javaOutput, Formatter.MAX_WIDTH, errors, indentMultiplier);
135+
Formatter.format(javaInput, javaOutput, options, errors);
144136
if (!errors.isEmpty()) {
145137
synchronized (outputLock) {
146138
for (FormatterDiagnostic error : errors) {

core/src/main/java/com/google/googlejavaformat/java/Formatter.java

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
import com.google.googlejavaformat.FormatterDiagnostic;
3030
import com.google.googlejavaformat.Op;
3131
import com.google.googlejavaformat.OpsBuilder;
32+
import com.google.googlejavaformat.java.JavaFormatterOptions.JavadocFormatter;
33+
import com.google.googlejavaformat.java.JavaFormatterOptions.SortImports;
34+
import com.google.googlejavaformat.java.JavaFormatterOptions.Style;
3235

3336
import org.eclipse.jdt.core.JavaCore;
3437
import org.eclipse.jdt.core.dom.AST;
@@ -74,36 +77,41 @@
7477
*/
7578
@Immutable
7679
public final class Formatter {
77-
static final int MAX_WIDTH = 100;
80+
7881
static final Range<Integer> EMPTY_RANGE = Range.closedOpen(-1, -1);
7982

83+
private final JavaFormatterOptions options;
84+
8085
/**
8186
* A new Formatter instance with default options.
8287
*/
8388
public Formatter() {
89+
this(new JavaFormatterOptions(JavadocFormatter.NONE, Style.GOOGLE, SortImports.NO));
90+
}
91+
92+
Formatter(JavaFormatterOptions options) {
93+
this.options = options;
8494
}
8595

8696
/**
8797
* Construct a {@code Formatter} given a Java compilation unit. Parses the code; builds a
8898
* {@link JavaInput} and the corresponding {@link JavaOutput}.
8999
* @param javaInput the input, a Java compilation unit
90100
* @param javaOutput the {@link JavaOutput}
91-
* @param maxWidth the maximum formatted width
101+
* @param options the {@link JavaFormatterOptions}
92102
* @param errors mutable list to receive errors
93-
* @param indentationMultiplier the multiplier for the unit of indent; the default is 1
94103
*/
95104
static void format(
96105
JavaInput javaInput,
97106
JavaOutput javaOutput,
98-
int maxWidth,
99-
List<FormatterDiagnostic> errors,
100-
int indentationMultiplier) {
107+
JavaFormatterOptions options,
108+
List<FormatterDiagnostic> errors) {
101109
ASTParser parser = ASTParser.newParser(AST.JLS8);
102110
parser.setSource(javaInput.getText().toCharArray());
103111
@SuppressWarnings("unchecked") // safe by specification
104-
Map<String, String> options = JavaCore.getOptions();
105-
JavaCore.setComplianceOptions(JavaCore.VERSION_1_8, options);
106-
parser.setCompilerOptions(options);
112+
Map<String, String> parserOptions = JavaCore.getOptions();
113+
JavaCore.setComplianceOptions(JavaCore.VERSION_1_8, parserOptions);
114+
parser.setCompilerOptions(parserOptions);
107115
CompilationUnit unit = (CompilationUnit) parser.createAST(null);
108116
javaInput.setCompilationUnit(unit);
109117
if (unit.getMessages().length > 0) {
@@ -114,11 +122,12 @@ static void format(
114122
}
115123
OpsBuilder builder = new OpsBuilder(javaInput, javaOutput, errors);
116124
// Output the compilation unit.
117-
new JavaInputAstVisitor(builder, indentationMultiplier).visit(unit);
125+
new JavaInputAstVisitor(builder, options.indentationMultiplier()).visit(unit);
118126
builder.sync(javaInput.getText().length());
119127
builder.drain();
120128
Doc doc = new DocBuilder().withOps(builder.build()).build();
121-
doc.computeBreaks(javaOutput.getCommentsHelper(), maxWidth, new Doc.State(+0, 0));
129+
doc.computeBreaks(
130+
javaOutput.getCommentsHelper(), options.maxLineLength(), new Doc.State(+0, 0));
122131
doc.write(javaOutput);
123132
javaOutput.flush();
124133
}
@@ -143,9 +152,9 @@ public void formatSource(CharSource input, CharSink output)
143152
*/
144153
public String formatSource(String input) throws FormatterException {
145154
JavaInput javaInput = new JavaInput(STDIN_FILENAME, input);
146-
JavaOutput javaOutput = new JavaOutput(javaInput, new JavaCommentsHelper());
155+
JavaOutput javaOutput = new JavaOutput(javaInput, new JavaCommentsHelper(options));
147156
List<FormatterDiagnostic> errors = new ArrayList<>();
148-
format(javaInput, javaOutput, MAX_WIDTH, errors, 1);
157+
format(javaInput, javaOutput, options, errors);
149158
if (!errors.isEmpty()) {
150159
throw new FormatterException(errors);
151160
}
@@ -171,9 +180,9 @@ public String formatSource(String input) throws FormatterException {
171180
public String formatSource(String input, List<Range<Integer>> characterRanges)
172181
throws FormatterException {
173182
JavaInput javaInput = new JavaInput(STDIN_FILENAME, input);
174-
JavaOutput javaOutput = new JavaOutput(javaInput, new JavaCommentsHelper());
183+
JavaOutput javaOutput = new JavaOutput(javaInput, new JavaCommentsHelper(options));
175184
List<FormatterDiagnostic> errors = new ArrayList<>();
176-
format(javaInput, javaOutput, MAX_WIDTH, errors, 1);
185+
format(javaInput, javaOutput, options, errors);
177186
if (!errors.isEmpty()) {
178187
throw new FormatterException(errors);
179188
}
@@ -198,9 +207,9 @@ public String formatSource(String input, List<Range<Integer>> characterRanges)
198207
public ImmutableList<Replacement> getFormatReplacements(
199208
String input, List<Range<Integer>> characterRanges) throws FormatterException {
200209
JavaInput javaInput = new JavaInput(STDIN_FILENAME, input);
201-
JavaOutput javaOutput = new JavaOutput(javaInput, new JavaCommentsHelper());
210+
JavaOutput javaOutput = new JavaOutput(javaInput, new JavaCommentsHelper(options));
202211
List<FormatterDiagnostic> errors = new ArrayList<>();
203-
format(javaInput, javaOutput, MAX_WIDTH, errors, 1);
212+
format(javaInput, javaOutput, options, errors);
204213
if (!errors.isEmpty()) {
205214
throw new FormatterException(errors);
206215
}

core/src/main/java/com/google/googlejavaformat/java/JavaCommentsHelper.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,26 @@
2626

2727
/** {@code JavaCommentsHelper} extends {@link CommentsHelper} to rewrite Java comments. */
2828
public final class JavaCommentsHelper implements CommentsHelper {
29+
2930
private static final Splitter NEWLINE_SPLITTER = Splitter.on('\n');
3031

32+
private final JavaFormatterOptions options;
33+
34+
public JavaCommentsHelper(JavaFormatterOptions options) {
35+
this.options = options;
36+
}
37+
3138
@Override
3239
public String rewrite(Tok tok, int maxWidth, int column0) {
3340
if (!tok.isComment()) {
3441
return tok.getOriginalText();
3542
}
36-
ArrayList<String> lines = new ArrayList<>();
37-
for (String line : NEWLINE_SPLITTER.splitToList(tok.getOriginalText())) {
43+
String text = tok.getOriginalText();
44+
if (tok.isJavadocComment()) {
45+
text = options.javadocFormatter().format(options, text, column0);
46+
}
47+
List<String> lines = new ArrayList<>();
48+
for (String line : NEWLINE_SPLITTER.split(text)) {
3849
lines.add(CharMatcher.whitespace().trimTrailingFrom(line));
3950
}
4051
if (lines.size() == 1) {

0 commit comments

Comments
 (0)