Skip to content

Commit

Permalink
Handle hard keywords in generated kotlin package name
Browse files Browse the repository at this point in the history
  • Loading branch information
Ant00000ny committed Jul 16, 2024
1 parent 5708b27 commit 8ff0c26
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ public class KotlinSourceCodeWriter implements SourceCodeWriter<KotlinSourceCode

private static final FormattingOptions FORMATTING_OPTIONS = new KotlinFormattingOptions();

// Taken from https://kotlinlang.org/docs/keyword-reference.html#hard-keywords
// except keywords contains `!` or `?` because they should be handled as invalid package names already
private static final Set<String> KOTLIN_HARD_KEYWORDS = Set.of(
"package", "as", "typealias", "class", "this", "super", "val", "var", "fun", "for", "null", "true", "false",
"is", "in", "throw", "return", "break", "continue", "object", "if", "try", "else", "while", "do", "when",
"interface", "typeof"
);

private final IndentingWriterFactory indentingWriterFactory;

public KotlinSourceCodeWriter(IndentingWriterFactory indentingWriterFactory) {
Expand All @@ -68,12 +76,18 @@ public void writeTo(SourceStructure structure, KotlinSourceCode sourceCode) thro
}
}

private static String escapeKotlinKeywords(String packageName) {
return Arrays.stream(packageName.split("\\."))
.map(segment -> KOTLIN_HARD_KEYWORDS.contains(segment) ? "`" + segment + "`" : segment)
.collect(Collectors.joining("."));
}

private void writeTo(SourceStructure structure, KotlinCompilationUnit compilationUnit) throws IOException {
Path output = structure.createSourceFile(compilationUnit.getPackageName(), compilationUnit.getName());
Files.createDirectories(output.getParent());
try (IndentingWriter writer = this.indentingWriterFactory.createIndentingWriter("kotlin",
Files.newBufferedWriter(output))) {
writer.println("package " + compilationUnit.getPackageName());
writer.println("package " + escapeKotlinKeywords(compilationUnit.getPackageName()));
writer.println();
Set<String> imports = determineImports(compilationUnit);
if (!imports.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,31 @@ void functionWithParameterAnnotation() throws IOException {
" fun something(@Service service: MyService) {", " }", "", "}");
}

@Test
void reservedKeywordsStartPackageName() throws IOException {
KotlinSourceCode sourceCode = new KotlinSourceCode();
sourceCode.createCompilationUnit("fun.example.demo", "Test");
List<String> lines = writeSingleType(sourceCode, "fun/example/demo/Test.kt");
assertThat(lines).containsExactly("package `fun`.example.demo");
}

@Test
void reservedKeywordsMiddlePackageName() throws IOException {
KotlinSourceCode sourceCode = new KotlinSourceCode();
sourceCode.createCompilationUnit("com.false.demo", "Test");
List<String> lines = writeSingleType(sourceCode, "com/false/demo/Test.kt");
assertThat(lines).containsExactly("package com.`false`.demo");
}

@Test
void reservedKeywordsEndPackageName() throws IOException {
KotlinSourceCode sourceCode = new KotlinSourceCode();
sourceCode.createCompilationUnit("com.example.in", "Test");
List<String> lines = writeSingleType(sourceCode, "com/example/in/Test.kt");
assertThat(lines).containsExactly("package com.example.`in`");
}


private List<String> writeSingleType(KotlinSourceCode sourceCode, String location) throws IOException {
Path source = writeSourceCode(sourceCode).resolve(location);
try (InputStream stream = Files.newInputStream(source)) {
Expand Down

0 comments on commit 8ff0c26

Please sign in to comment.