Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[0.10] Support Smithy IDL Serialization #284

Merged
merged 16 commits into from
Feb 27, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Add writeInline method to CodeWriter
This adds a method to CodeWriter which allow for writing without
having a trailing newline or leading indentation inserted. This can
be very useful when you want to write part of a line without knowing
what the whole line will contain.

This does preserve some safety in that it will intercept newlines to
treat them as normal, but it is still potentially dangerous if not
used carefully.
  • Loading branch information
JordonPhillips committed Feb 21, 2020
commit 543857c269ee78779635a2eec7e414d2de694cdb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Deque;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -944,6 +945,43 @@ public final CodeWriter write(Object content, Object... args) {
return this;
}

/**
* Writes text to the CodeWriter without appending a newline or prefixing indentation.
*
* <p>If newlines are present in the given string, each of those lines will receive proper indentation.
*
* @param content Content to write.
* @param args String arguments to use for formatting.
* @return Returns the CodeWriter.
*/
public final CodeWriter writeInline(Object content, Object... args) {
String value = formatter.format(content, currentState.indentText, this, args);
ArrayList<String> lines = new ArrayList<>(Arrays.asList(value.split(newlineRegexQuoted, -1)));
JordonPhillips marked this conversation as resolved.
Show resolved Hide resolved

// The first line is written directly, with no added indentation or newline
currentState.write(lines.remove(0));

// If there aren't any additional lines, return.
if (lines.isEmpty()) {
return this;
}

// If there are additional lines, they need to be handled properly. So insert a newline.
currentState.write(newline);

// We don't want to append a newline, so remove the last line for handling later.
String lastLine = lines.remove(lines.size() - 1);

// Write all the intermediate lines as normal.
for (String line : lines) {
currentState.writeLine(line + newline);
}

// Write the final line with proper indentation, but without an appended newline.
currentState.writeLine(lastLine);
return this;
}

/**
* Optionally writes text to the CodeWriter and appends a newline
* if a value is present.
Expand Down Expand Up @@ -1115,6 +1153,14 @@ void putInterceptor(String section, Consumer<Object> interceptor) {
interceptors.computeIfAbsent(section, s -> new ArrayList<>()).add(interceptor);
}

void write(String contents) {
if (builder == null) {
builder = new StringBuilder();
}
builder.append(contents);
trimSpaces(false);
}

void writeLine(String line) {
if (builder == null) {
builder = new StringBuilder();
Expand All @@ -1125,21 +1171,31 @@ void writeLine(String line) {
builder.append(line);

// Trim all trailing spaces before the trailing (customizable) newline.
if (trimTrailingSpaces) {
int newlineLength = newline.length();
int toRemove = 0;
for (int i = builder.length() - 1 - newlineLength; i > 0; i--) {
if (builder.charAt(i) == ' ') {
toRemove++;
} else {
break;
}
}
// Remove the slice of the string that is made up of whitespace before the newline.
if (toRemove > 0) {
builder.delete(builder.length() - newlineLength - toRemove, builder.length() - newlineLength);
trimSpaces(true);
}

private void trimSpaces(boolean skipNewline) {
if (!trimTrailingSpaces) {
return;
}

int skipLength = 0;
if (skipNewline) {
skipLength = newline.length();
}

int toRemove = 0;
for (int i = builder.length() - 1 - skipLength; i > 0; i--) {
if (builder.charAt(i) == ' ') {
toRemove++;
} else {
break;
}
}
// Remove the slice of the string that is made up of whitespace before the newline.
if (toRemove > 0) {
builder.delete(builder.length() - skipLength - toRemove, builder.length() - skipLength);
}
}

private void indent(int levels, String indentText) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -505,4 +505,46 @@ public void poppedSectionsEscapeDollars() {

assertThat(result, equalTo("$Hello\n"));
}

@Test
public void canWriteInline() {
String result = CodeWriter.createDefault()
.writeInline("foo")
.writeInline(", bar")
.toString();

assertThat(result, equalTo("foo, bar"));
}

@Test
public void writeInlineHandlesSingleNewline() {
String result = CodeWriter.createDefault()
.writeInline("foo").indent()
.writeInline(":\nbar")
.toString();

assertThat(result, equalTo("foo:\n bar"));
}

@Test
public void writeInlineHandlesMultipleNewlines() {
String result = CodeWriter.createDefault()
.writeInline("foo:")
.writeInline(" [").indent()
.writeInline("\nbar,\nbaz,\nbam,")
.dedent().writeInline("\n]")
.toString();

assertThat(result, equalTo("foo: [\n bar,\n baz,\n bam,\n]"));
}

@Test
public void writeInlineStripsSpaces() {
String result = CodeWriter.createDefault()
.trimTrailingSpaces()
.writeInline("foo ")
.toString();

assertThat(result, equalTo("foo"));
}
}