A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/google/google-java-format/commit/ce3cb59a8d649359a8e6e7fcc5f2f21bb79b3df1 below:

Re-indent text blocks · google/google-java-format@ce3cb59 · GitHub

14 14 15 15

package com.google.googlejavaformat.java;

16 16 17 +

import static com.google.common.collect.ImmutableList.toImmutableList;

17 18

import static com.google.common.collect.Iterables.getLast;

18 19

import static java.lang.Math.min;

19 20

import static java.nio.charset.StandardCharsets.UTF_8;

44 45

import com.sun.tools.javac.util.Position;

45 46

import java.io.IOException;

46 47

import java.io.UncheckedIOException;

48 +

import java.lang.reflect.Method;

47 49

import java.net.URI;

48 50

import java.util.ArrayDeque;

49 51

import java.util.ArrayList;

59 61

import javax.tools.JavaFileObject;

60 62

import javax.tools.SimpleJavaFileObject;

61 63

import javax.tools.StandardLocation;

64 +

import org.checkerframework.checker.nullness.qual.Nullable;

62 65 63 66

/** Wraps string literals that exceed the column limit. */

64 67

public final class StringWrapper {

@@ -72,7 +75,7 @@ public static String wrap(String input, Formatter formatter) throws FormatterExc

72 75

*/

73 76

static String wrap(final int columnLimit, String input, Formatter formatter)

74 77

throws FormatterException {

75 -

if (!longLines(columnLimit, input)) {

78 +

if (!needWrapping(columnLimit, input)) {

76 79

// fast path

77 80

return input;

78 81

}

@@ -111,20 +114,56 @@ static String wrap(final int columnLimit, String input, Formatter formatter)

111 114 112 115

private static TreeRangeMap<Integer, String> getReflowReplacements(

113 116

int columnLimit, final String input) throws FormatterException {

114 -

JCTree.JCCompilationUnit unit = parse(input, /* allowStringFolding= */ false);

115 -

String separator = Newlines.guessLineSeparator(input);

117 +

return new Reflower(columnLimit, input).getReflowReplacements();

118 +

}

119 + 120 +

private static class Reflower {

121 + 122 +

private final String input;

123 +

private final int columnLimit;

124 +

private final String separator;

125 +

private final JCTree.JCCompilationUnit unit;

126 +

private final Position.LineMap lineMap;

127 + 128 +

Reflower(int columnLimit, String input) throws FormatterException {

129 +

this.columnLimit = columnLimit;

130 +

this.input = input;

131 +

this.separator = Newlines.guessLineSeparator(input);

132 +

this.unit = parse(input, /* allowStringFolding= */ false);

133 +

this.lineMap = unit.getLineMap();

134 +

}

135 + 136 +

TreeRangeMap<Integer, String> getReflowReplacements() {

137 +

// Paths to string literals that extend past the column limit.

138 +

List<TreePath> longStringLiterals = new ArrayList<>();

139 +

// Paths to text blocks to be re-indented.

140 +

List<Tree> textBlocks = new ArrayList<>();

141 +

new LongStringsAndTextBlockScanner(longStringLiterals, textBlocks)

142 +

.scan(new TreePath(unit), null);

143 +

TreeRangeMap<Integer, String> replacements = TreeRangeMap.create();

144 +

indentTextBlocks(replacements, textBlocks);

145 +

wrapLongStrings(replacements, longStringLiterals);

146 +

return replacements;

147 +

}

148 + 149 +

private class LongStringsAndTextBlockScanner extends TreePathScanner<Void, Void> {

150 + 151 +

private final List<TreePath> longStringLiterals;

152 +

private final List<Tree> textBlocks;

153 + 154 +

LongStringsAndTextBlockScanner(List<TreePath> longStringLiterals, List<Tree> textBlocks) {

155 +

this.longStringLiterals = longStringLiterals;

156 +

this.textBlocks = textBlocks;

157 +

}

116 158 117 -

// Paths to string literals that extend past the column limit.

118 -

List<TreePath> toFix = new ArrayList<>();

119 -

final Position.LineMap lineMap = unit.getLineMap();

120 -

new TreePathScanner<Void, Void>() {

121 159

@Override

122 160

public Void visitLiteral(LiteralTree literalTree, Void aVoid) {

123 161

if (literalTree.getKind() != Kind.STRING_LITERAL) {

124 162

return null;

125 163

}

126 164

int pos = getStartPosition(literalTree);

127 165

if (input.substring(pos, min(input.length(), pos + 3)).equals("\"\"\"")) {

166 +

textBlocks.add(literalTree);

128 167

return null;

129 168

}

130 169

Tree parent = getCurrentPath().getParentPath().getLeaf();

@@ -140,44 +179,114 @@ public Void visitLiteral(LiteralTree literalTree, Void aVoid) {

140 179

if (lineMap.getColumnNumber(lineEnd) - 1 <= columnLimit) {

141 180

return null;

142 181

}

143 -

toFix.add(getCurrentPath());

182 +

longStringLiterals.add(getCurrentPath());

144 183

return null;

145 184

}

146 -

}.scan(new TreePath(unit), null);

147 - 148 -

TreeRangeMap<Integer, String> replacements = TreeRangeMap.create();

149 -

for (TreePath path : toFix) {

150 -

// Find the outermost contiguous enclosing concatenation expression

151 -

TreePath enclosing = path;

152 -

while (enclosing.getParentPath().getLeaf().getKind() == Tree.Kind.PLUS) {

153 -

enclosing = enclosing.getParentPath();

185 +

}

186 + 187 +

private void indentTextBlocks(

188 +

TreeRangeMap<Integer, String> replacements, List<Tree> textBlocks) {

189 +

for (Tree tree : textBlocks) {

190 +

int startPosition = getStartPosition(tree);

191 +

int endPosition = getEndPosition(unit, tree);

192 +

String text = input.substring(startPosition, endPosition);

193 + 194 +

// Find the source code of the text block with incidental whitespace removed.

195 +

// The first line of the text block is always """, and it does not affect incidental

196 +

// whitespace.

197 +

ImmutableList<String> initialLines = text.lines().collect(toImmutableList());

198 +

String stripped = stripIndent(initialLines.stream().skip(1).collect(joining(separator)));

199 +

ImmutableList<String> lines = stripped.lines().collect(toImmutableList());

200 +

int deindent =

201 +

initialLines.get(1).stripTrailing().length() - lines.get(0).stripTrailing().length();

202 + 203 +

int startColumn = lineMap.getColumnNumber(startPosition);

204 +

String prefix =

205 +

(deindent == 0 || lines.stream().anyMatch(x -> x.length() + startColumn > columnLimit))

206 +

? ""

207 +

: " ".repeat(startColumn - 1);

208 + 209 +

StringBuilder output = new StringBuilder("\"\"\"");

210 +

for (int i = 0; i < lines.size(); i++) {

211 +

String line = lines.get(i);

212 +

String trimmed = line.stripLeading().stripTrailing();

213 +

output.append(separator);

214 +

if (!trimmed.isEmpty()) {

215 +

// Don't add incidental leading whitespace to empty lines

216 +

output.append(prefix);

217 +

}

218 +

if (i == lines.size() - 1 && trimmed.equals("\"\"\"")) {

219 +

// If the trailing line is just """, indenting is more than the prefix of incidental

220 +

// whitespace has no effect, and results in a javac text-blocks warning that 'trailing

221 +

// white space will be removed'.

222 +

output.append("\"\"\"");

223 +

} else {

224 +

output.append(line);

225 +

}

226 +

}

227 +

replacements.put(Range.closedOpen(startPosition, endPosition), output.toString());

154 228

}

155 -

// Is the literal being wrapped the first in a chain of concatenation expressions?

156 -

// i.e. `ONE + TWO + THREE`

157 -

// We need this information to handle continuation indents.

158 -

AtomicBoolean first = new AtomicBoolean(false);

159 -

// Finds the set of string literals in the concat expression that includes the one that needs

160 -

// to be wrapped.

161 -

List<Tree> flat = flatten(input, unit, path, enclosing, first);

162 -

// Zero-indexed start column

163 -

int startColumn = lineMap.getColumnNumber(getStartPosition(flat.get(0))) - 1;

164 - 165 -

// Handling leaving trailing non-string tokens at the end of the literal,

166 -

// e.g. the trailing `);` in `foo("...");`.

167 -

int end = getEndPosition(unit, getLast(flat));

168 -

int lineEnd = end;

169 -

while (Newlines.hasNewlineAt(input, lineEnd) == -1) {

170 -

lineEnd++;

229 +

}

230 + 231 +

private void wrapLongStrings(

232 +

TreeRangeMap<Integer, String> replacements, List<TreePath> longStringLiterals) {

233 +

for (TreePath path : longStringLiterals) {

234 +

// Find the outermost contiguous enclosing concatenation expression

235 +

TreePath enclosing = path;

236 +

while (enclosing.getParentPath().getLeaf().getKind() == Kind.PLUS) {

237 +

enclosing = enclosing.getParentPath();

238 +

}

239 +

// Is the literal being wrapped the first in a chain of concatenation expressions?

240 +

// i.e. `ONE + TWO + THREE`

241 +

// We need this information to handle continuation indents.

242 +

AtomicBoolean first = new AtomicBoolean(false);

243 +

// Finds the set of string literals in the concat expression that includes the one that

244 +

// needs

245 +

// to be wrapped.

246 +

List<Tree> flat = flatten(input, unit, path, enclosing, first);

247 +

// Zero-indexed start column

248 +

int startColumn = lineMap.getColumnNumber(getStartPosition(flat.get(0))) - 1;

249 + 250 +

// Handling leaving trailing non-string tokens at the end of the literal,

251 +

// e.g. the trailing `);` in `foo("...");`.

252 +

int end = getEndPosition(unit, getLast(flat));

253 +

int lineEnd = end;

254 +

while (Newlines.hasNewlineAt(input, lineEnd) == -1) {

255 +

lineEnd++;

256 +

}

257 +

int trailing = lineEnd - end;

258 + 259 +

// Get the original source text of the string literals, excluding `"` and `+`.

260 +

ImmutableList<String> components = stringComponents(input, unit, flat);

261 +

replacements.put(

262 +

Range.closedOpen(getStartPosition(flat.get(0)), getEndPosition(unit, getLast(flat))),

263 +

reflow(separator, columnLimit, startColumn, trailing, components, first.get()));

171 264

}

172 -

int trailing = lineEnd - end;

265 +

}

266 +

}

267 + 268 +

private static final Method STRIP_INDENT = getStripIndent();

269 + 270 +

private static @Nullable Method getStripIndent() {

271 +

if (Runtime.version().feature() < 15) {

272 +

return null;

273 +

}

274 +

try {

275 +

return String.class.getMethod("stripIndent");

276 +

} catch (NoSuchMethodException e) {

277 +

throw new LinkageError(e.getMessage(), e);

278 +

}

279 +

}

173 280 174 -

// Get the original source text of the string literals, excluding `"` and `+`.

175 -

ImmutableList<String> components = stringComponents(input, unit, flat);

176 -

replacements.put(

177 -

Range.closedOpen(getStartPosition(flat.get(0)), getEndPosition(unit, getLast(flat))),

178 -

reflow(separator, columnLimit, startColumn, trailing, components, first.get()));

281 +

private static String stripIndent(String input) {

282 +

if (STRIP_INDENT == null) {

283 +

return input;

284 +

}

285 +

try {

286 +

return (String) STRIP_INDENT.invoke(input);

287 +

} catch (ReflectiveOperationException e) {

288 +

throw new LinkageError(e.getMessage(), e);

179 289

}

180 -

return replacements;

181 290

}

182 291 183 292

/**

@@ -364,13 +473,16 @@ private static int getStartPosition(Tree tree) {

364 473

return ((JCTree) tree).getStartPosition();

365 474

}

366 475 367 -

/** Returns true if any lines in the given Java source exceed the column limit. */

368 -

private static boolean longLines(int columnLimit, String input) {

476 +

/**

477 +

* Returns true if any lines in the given Java source exceed the column limit, or contain a {@code

478 +

* """} that could indicate a text block.

479 +

*/

480 +

private static boolean needWrapping(int columnLimit, String input) {

369 481

// TODO(cushon): consider adding Newlines.lineIterable?

370 482

Iterator<String> it = Newlines.lineIterator(input);

371 483

while (it.hasNext()) {

372 484

String line = it.next();

373 -

if (line.length() > columnLimit) {

485 +

if (line.length() > columnLimit || line.contains("\"\"\"")) {

374 486

return true;

375 487

}

376 488

}

@@ -385,7 +497,6 @@ private static JCTree.JCCompilationUnit parse(String source, boolean allowString

385 497

context.put(DiagnosticListener.class, diagnostics);

386 498

Options.instance(context).put("--enable-preview", "true");

387 499

Options.instance(context).put("allowStringFolding", Boolean.toString(allowStringFolding));

388 -

JCTree.JCCompilationUnit unit;

389 500

JavacFileManager fileManager = new JavacFileManager(context, true, UTF_8);

390 501

try {

391 502

fileManager.setLocation(StandardLocation.PLATFORM_CLASS_PATH, ImmutableList.of());

@@ -404,7 +515,7 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) {

404 515

JavacParser parser =

405 516

parserFactory.newParser(

406 517

source, /* keepDocComments= */ true, /* keepEndPos= */ true, /* keepLineMap= */ true);

407 -

unit = parser.parseCompilationUnit();

518 +

JCTree.JCCompilationUnit unit = parser.parseCompilationUnit();

408 519

unit.sourcefile = sjfo;

409 520

Iterable<Diagnostic<? extends JavaFileObject>> errorDiagnostics =

410 521

Iterables.filter(diagnostics.getDiagnostics(), Formatter::errorDiagnostic);


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4