Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions debugger/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
/node_modules
/.pnp
.pnp.js
yarn.lock
package-lock.json

# testing
/coverage
Expand Down
8 changes: 8 additions & 0 deletions debugger/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
React App that helps Debugging a javaInput's AST.

1. Run only one test from [FormatterIntegrationTest](https://github.com/palantir/palantir-java-format/blob/0ad916e4f27b5aab3870d633a16c50192b6e54cc/palantir-java-format/src/test/java/com/palantir/javaformat/java/FormatterIntegrationTest.java#L66) with ["debugOutput" = true](https://github.com/palantir/palantir-java-format/blob/0ad916e4f27b5aab3870d633a16c50192b6e54cc/palantir-java-format/src/test/java/com/palantir/javaformat/java/FormatterIntegrationTest.java#L66)
2. Run `cd debugger && NODE_OPTIONS=--openssl-legacy-provider yarn start` that will open the app in the browser (<code>localhost:3000</code>)


-----

This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).

## Available Scripts
Expand Down
8 changes: 4 additions & 4 deletions debugger/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@blueprintjs/core": "^3.20.0",
"@types/jest": "24.0.23",
"@types/node": "12.12.7",
"@types/react": "16.9.11",
"@types/react-dom": "16.9.4",
"react": "^16.11.0",
"react-dom": "^16.11.0",
"react-scripts": "3.2.0",
"typescript": "3.7.2",
"@blueprintjs/core": "^3.20.0",
"react-treebeard": "^3.2.4"
"react-scripts": "^3.2.0",
"react-treebeard": "^3.2.4",
"typescript": "3.7.2"
},
"scripts": {
"start": "react-scripts start",
Expand Down
10,546 changes: 0 additions & 10,546 deletions debugger/yarn.lock

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public NativeImageFormatterService(Path nativeImagePath) {

@Override
public ImmutableList<Replacement> getFormatReplacements(String input, Collection<Range<Integer>> ranges) {
Optional<String> output = Optional.empty();
try {
FormatterNativeImageArgs command = FormatterNativeImageArgs.builder()
.nativeImagePath(nativeImagePath)
Expand All @@ -53,14 +54,15 @@ public ImmutableList<Replacement> getFormatReplacements(String input, Collection
ranges.stream().map(RangeUtils::toStringRange).collect(Collectors.toList()))
.build();

Optional<String> output = FormatterCommandRunner.runWithStdin(
output = FormatterCommandRunner.runWithStdin(
command.toArgs(), input, Optional.ofNullable(nativeImagePath.getParent()));
if (output.isEmpty() || output.get().isEmpty()) {
return ImmutableList.of();
}
return MAPPER.readValue(output.get(), new TypeReference<>() {});
} catch (IOException e) {
throw new UncheckedIOException("Error running the native image command", e);
throw new UncheckedIOException(
String.format("Error running the native image command; received output: %s", output), e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@
"type": "com.google.common.collect.RegularImmutableList",
"allDeclaredFields": true
},
{
"type": "java.util.ImmutableCollections$AbstractImmutableList",
"allDeclaredFields": true
},
{
"type": "java.util.ImmutableCollections$AbstractImmutableCollection",
"allDeclaredFields": true
},
{
"type": "java.util.ImmutableCollections$List12",
"allDeclaredFields": true
},
{
"type": "com.google.common.collect.SingletonImmutableList",
"allDeclaredFields": true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.palantir.javaformat.Input;
import com.palantir.javaformat.Op;
import com.palantir.javaformat.Output;
import com.palantir.javaformat.java.StringWrapper;
import java.util.Optional;

/** A leaf {@link Doc} for a token. */
Expand Down Expand Up @@ -106,6 +107,11 @@ public void add(DocBuilder builder) {

@Override
protected float computeWidth() {
if (token.getTok().getOriginalText().startsWith(StringWrapper.TEXT_BLOCK_DELIMITER)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

before - when the textBlock+methods would exceed 120 characters (maxWidthLimit), the block would look like this:

    """
    hello %s this exceeds 120 characters nasddnsadalsdaslda
    """
        .formatted("world");

now:

    """
    hello %s this exceeds 120 characters nasddnsadalsdaslda
    """.formatted("world");

// Palantir-specific: The size of a text block should not impact line length. This ensures that methods
// applied to text blocks remain on the same line and are not split into multiple lines.
return StringWrapper.TEXT_BLOCK_DELIMITER.length();
}
return token.getTok().length();
}

Expand All @@ -123,6 +129,11 @@ protected Range<Integer> computeRange() {
public State computeBreaks(
CommentsHelper commentsHelper, int maxWidth, State state, Obs.ExplorationNode observationNode) {
String text = token.getTok().getOriginalText();
if (token.getTok().getOriginalText().startsWith(StringWrapper.TEXT_BLOCK_DELIMITER)) {
// Palantir-specific: The size of a text block should not impact line length. This ensures that methods
// applied to text blocks remain on the same line and are not split into multiple lines.
return state.withColumn(state.column() + StringWrapper.TEXT_BLOCK_DELIMITER.length());
}
return state.withColumn(state.column() + text.length());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,18 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.datatype.guava.GuavaModule;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Range;
import com.google.common.collect.RangeSet;
import com.google.common.collect.TreeRangeSet;
import com.palantir.javaformat.Utils;
import java.io.UncheckedIOException;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;

/** Encapsulates information about a file to be formatted, including which parts of the file to format. */
class FormatFileCallable implements Callable<String> {
private final ObjectMapper MAPPER =
private static final ObjectMapper MAPPER =
JsonMapper.builder().addModule(new GuavaModule()).build();

private final String input;
Expand All @@ -49,14 +50,29 @@ public String call() throws FormatterException {

Formatter formatter = Formatter.createFormatter(options);
if (parameters.outputReplacements()) {
return formatReplacements(formatter);
RangeSet<Integer> characterRanges = characterRanges(input);
Set<Range<Integer>> rangesToChange = characterRanges.asRanges();
List<Replacement> replacements = formatter.getFormatReplacements(input, rangesToChange);
if (parameters.reflowLongStrings()) {
String formattedText = Utils.applyReplacements(input, replacements);
// avoid trying to wrap the input unless the lines needing wrapping are part of the "characterRanges"
if (!StringWrapper.linesNeedWrapping(options.maxLineLength(), formattedText, characterRanges)) {
return writeFormatReplacements(replacements);
}
String wrappedFormattedText = StringWrapper.wrap(options.maxLineLength(), formattedText, formatter);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same behaviour now as with the gradle formatter task:

.

The alternative would have been to directly call the same method in the Intellij plugin, however I think this would be a bit more optimal - because when there is no need to call the wrapper, we can simply return just the replacement ranges. Worst case happens here where we have to send back the full document range to be reformatted.

// if no wrapping change happened, return the initial replacements
if (wrappedFormattedText.equals(formattedText)) {
return writeFormatReplacements(replacements);
}
return writeFormatReplacements(List.of(Replacement.create(0, input.length(), wrappedFormattedText)));
} else {
return writeFormatReplacements(replacements);
}
}
return formatFile(formatter);
}

private String formatReplacements(Formatter formatter) throws FormatterException {
ImmutableList<Replacement> replacements =
formatter.getFormatReplacements(input, characterRanges(input).asRanges());
String writeFormatReplacements(List<Replacement> replacements) throws FormatterException {
try {
return MAPPER.writeValueAsString(replacements);
} catch (JsonProcessingException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@
import static com.palantir.javaformat.java.Trees.precedence;
import static com.palantir.javaformat.java.Trees.skipParen;
import static com.sun.source.tree.Tree.Kind.ANNOTATION;
import static com.sun.source.tree.Tree.Kind.BLOCK;
import static com.sun.source.tree.Tree.Kind.EXTENDS_WILDCARD;
import static com.sun.source.tree.Tree.Kind.METHOD_INVOCATION;
import static com.sun.source.tree.Tree.Kind.STRING_LITERAL;
import static java.util.stream.Collectors.toList;

Expand Down Expand Up @@ -2657,6 +2655,7 @@ void visitDot(ExpressionTree node0) {
List<ExpressionTree> items = new ArrayList<>(stack);

boolean needDot = false;
boolean isTextBlock = false;

// The dot chain started with a primary expression: output it normally, and indent
// the rest of the chain +4.
Expand All @@ -2668,17 +2667,31 @@ void visitDot(ExpressionTree node0) {
scan(getArrayBase(node), null);
token(".");
} else {
// Special case for text blocks: if the node is a string literal that ends with """,
// don't add a break after it
if (node instanceof LiteralTree && node.getKind() == Tree.Kind.STRING_LITERAL) {
String sourceForNode = getSourceForNode(node, getCurrentPath());
isTextBlock = sourceForNode.trim().endsWith(StringWrapper.TEXT_BLOCK_DELIMITER);
}

builder.open(OpenOp.builder()
.debugName("visitDot")
.plusIndent(plusFour)
.breakBehaviour(BreakBehaviours.preferBreakingLastInnerLevel(true))
.breakBehaviour(
isTextBlock
? BreakBehaviours.breakOnlyIfInnerLevelsThenFitOnOneLine(false)
: BreakBehaviours.preferBreakingLastInnerLevel(true))
.breakabilityIfLastLevel(
LastLevelBreakability.ACCEPT_INLINE_CHAIN_IF_SIMPLE_OTHERWISE_CHECK_INNER)
isTextBlock
? LastLevelBreakability.ACCEPT_INLINE_CHAIN
: LastLevelBreakability.ACCEPT_INLINE_CHAIN_IF_SIMPLE_OTHERWISE_CHECK_INNER)
.columnLimitBeforeLastBreak(METHOD_CHAIN_COLUMN_LIMIT)
.isSimple(false)
.build());
scan(getArrayBase(node), null);
builder.breakOp();
if (!isTextBlock) {
builder.breakOp();
}
needDot = true;
}
formatArrayIndices(getArrayIndices(node));
Expand Down
Loading