Skip to content

Commit

Permalink
fix: fix pretty-printing of special characters in literals (#3209)
Browse files Browse the repository at this point in the history
  • Loading branch information
Egor18 authored and monperrus committed Jan 21, 2020
1 parent 99775fc commit 1b17dc7
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 12 deletions.
10 changes: 0 additions & 10 deletions src/main/java/spoon/reflect/visitor/LiteralHelper.java
Expand Up @@ -105,16 +105,6 @@ public static <T> String getLiteralToken(CtLiteral<T> literal) {
static void appendCharLiteral(StringBuilder sb, Character c, boolean mayContainsSpecialCharacter) {
if (!mayContainsSpecialCharacter) {
sb.append(c);
} else if (Character.UnicodeBlock.of(c) != Character.UnicodeBlock.BASIC_LATIN) {
if (c < 0x10) {
sb.append("\\u000" + Integer.toHexString(c));
} else if (c < 0x100) {
sb.append("\\u00" + Integer.toHexString(c));
} else if (c < 0x1000) {
sb.append("\\u0" + Integer.toHexString(c));
} else {
sb.append("\\u" + Integer.toHexString(c));
}
} else {
switch (c) {
case '\b':
Expand Down
45 changes: 45 additions & 0 deletions src/test/java/spoon/test/literal/UnicodeBugTest.java
@@ -0,0 +1,45 @@
package spoon.test.literal;

import org.junit.Test;
import spoon.Launcher;
import spoon.processing.AbstractProcessor;
import spoon.reflect.CtModel;
import spoon.reflect.code.CtBinaryOperator;
import spoon.reflect.code.CtCodeElement;
import spoon.reflect.code.CtLiteral;
import spoon.reflect.declaration.CtField;
import spoon.reflect.visitor.filter.TypeFilter;
import spoon.support.compiler.VirtualFile;

import static org.junit.Assert.assertEquals;

// bug case kindly provided by @Banbury
// in https://github.com/INRIA/spoon/issues/3203
public class UnicodeBugTest {

@Test
public void testUnicodeBug() {
Launcher launcher = new Launcher();
launcher.addInputResource(new VirtualFile("class A { String s = \"Hellö \" + \"Wörld!\"; }"));
launcher.buildModel();
launcher.addProcessor(new StringConcatProcessor());
launcher.process();
CtModel model = launcher.getModel();
CtField<?> field = model.getElements(new TypeFilter<>(CtField.class)).get(0);
assertEquals(field.toString(), "java.lang.String s = \"Hellö Wörld!\";");
}

private class StringConcatProcessor extends AbstractProcessor<CtLiteral<?>> {
@Override
public boolean isToBeProcessed(CtLiteral<?> candidate) {
return candidate.getType().isSubtypeOf(getFactory().Type().STRING) &&
candidate.getParent() instanceof CtBinaryOperator;
}

@Override
public void process(CtLiteral<?> element) {
CtCodeElement s = ((CtBinaryOperator<?>) element.getParent()).partiallyEvaluate();
element.getParent().replace(s);
}
}
}
4 changes: 2 additions & 2 deletions src/test/java/spoon/test/strings/StringLiteralTest.java
Expand Up @@ -61,8 +61,8 @@ public void testSnippetFullClass() {
assertEquals("java.lang.String f0 = \"toto\";", f0.toString());
assertEquals("java.lang.String f1 = \"\\n\";", f1.toString());
assertEquals("char c1 = '\\n';", c1.toString());
assertEquals("java.lang.String f2 = \"\\u20ac\";", f2.toString());
assertEquals("char c2 = '\\u20ac';", c2.toString());
assertEquals("java.lang.String f2 = \"\";", f2.toString());
assertEquals("char c2 = '';", c2.toString());
assertEquals("java.lang.String f3 = \"\";", f3.toString());
assertEquals("char c3 = '€';", c3.toString());
assertEquals("java.lang.String f4 = \"\\t\";", f4.toString());
Expand Down

0 comments on commit 1b17dc7

Please sign in to comment.