Skip to content

Commit

Permalink
feat: Add configurable encoding of processed source code (#5350)
Browse files Browse the repository at this point in the history
  • Loading branch information
tenax66 authored Jul 20, 2023
1 parent d46391f commit dae341a
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 6 deletions.
30 changes: 24 additions & 6 deletions src/main/java/spoon/support/JavaOutputProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
import spoon.support.compiler.SpoonProgress;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -39,6 +39,8 @@ public class JavaOutputProcessor extends AbstractProcessor<CtNamedElement> imple

List<File> printedFiles = new ArrayList<>();

private Charset charset = Charset.defaultCharset();

/**
* @param printer the PrettyPrinter to use for written the files
*/
Expand Down Expand Up @@ -75,6 +77,22 @@ public File getOutputDirectory() {
return this.getEnvironment().getSourceOutputDirectory();
}

/**
* Gets the charset.
* @return the charset used for processed source code.
*/
public Charset getCharset() {
return this.charset;
}

/**
* Sets the charset.
* @param charset the charset used for processed source code.
*/
public void setCharset(Charset charset) {
this.charset = charset;
}

@Override
public void init() {
// Skip loading properties
Expand Down Expand Up @@ -123,7 +141,7 @@ public void createJavaFile(CtType<?> element) {
printedFiles.add(file);
}
// print type
try (PrintStream stream = new PrintStream(file)) {
try (PrintStream stream = new PrintStream(file, charset)) {
stream.print(printer.getResult());
for (CtType<?> t : toBePrinted) {
lineNumberMappings.put(t.getQualifiedName(), printer.getLineNumberMapping());
Expand Down Expand Up @@ -161,9 +179,9 @@ private void createPackageFile(CtPackage pack) {
if (!printedFiles.contains(packageAnnot)) {
printedFiles.add(packageAnnot);
}
try (PrintStream stream = new PrintStream(packageAnnot)) {
try (PrintStream stream = new PrintStream(packageAnnot, charset)) {
stream.println(getPrinter().printPackageInfo(pack));
} catch (FileNotFoundException e) {
} catch (IOException e) {
Launcher.LOGGER.error(e.getMessage(), e);
}
}
Expand All @@ -174,9 +192,9 @@ private void createModuleFile(CtModule module) {
if (!printedFiles.contains(moduleFile)) {
printedFiles.add(moduleFile);
}
try (PrintStream stream = new PrintStream(moduleFile)) {
try (PrintStream stream = new PrintStream(moduleFile, charset)) {
stream.println(getPrinter().printModuleInfo(module));
} catch (FileNotFoundException e) {
} catch (IOException e) {
Launcher.LOGGER.error(e.getMessage(), e);
}
}
Expand Down
51 changes: 51 additions & 0 deletions src/test/java/spoon/support/JavaOutputProcessorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,63 @@
import spoon.reflect.factory.Factory;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

class JavaOutputProcessorTest {

@Test
void testCreateJavaFileAssertFileCreated(@TempDir File tempDir) {
// contract : createJavaFile creates a Java file and prints it

// arrange
Launcher launcher = new Launcher();
launcher.setSourceOutputDirectory(tempDir.getAbsolutePath());
launcher.getEnvironment().setComplianceLevel(9);
Factory factory = launcher.getFactory();

CtClass<?> ctClass = factory.Class().create("spoon.support.EmptyClass");
JavaOutputProcessor javaOutputProcessor = new JavaOutputProcessor();
javaOutputProcessor.setFactory(factory);

// act
javaOutputProcessor.process(ctClass);

// assert
File expectedFile = tempDir.toPath().resolve("spoon/support/EmptyClass.java").toFile();
assertTrue(expectedFile.exists());
assertEquals(1, javaOutputProcessor.printedFiles.size());
}

@Test
void testCreateJavaFileAssertFileEncodingChanged(@TempDir File tempDir) throws Exception {

// arrange
Launcher launcher = new Launcher();
launcher.setSourceOutputDirectory(tempDir.getAbsolutePath());
launcher.getEnvironment().setComplianceLevel(9);
Factory factory = launcher.getFactory();

// use characters encoded differently in ISO-8859-01 and UTFs
String code = "class ÈmptyÇlàss {}";
CtClass<?> ctClass = Launcher.parseClass(code);

JavaOutputProcessor javaOutputProcessor = new JavaOutputProcessor();
javaOutputProcessor.setCharset(StandardCharsets.ISO_8859_1);
javaOutputProcessor.setFactory(factory);

// act
javaOutputProcessor.process(ctClass);

// assert
File expectedFile = tempDir.toPath().resolve("ÈmptyÇlàss.java").toFile();

byte[] bytes = Files.readAllBytes(expectedFile.toPath());
assertEquals(code, new String(bytes, StandardCharsets.ISO_8859_1));
}

@Test
void testCreateModuleFileAssertAnnotationFileCreated(@TempDir File tempDir) {
Expand Down

0 comments on commit dae341a

Please sign in to comment.