Skip to content

Commit

Permalink
code formatter interface
Browse files Browse the repository at this point in the history
  • Loading branch information
vincentlauvlwj committed Aug 27, 2023
1 parent 5c3416f commit b194c68
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,36 +20,19 @@ import com.google.devtools.ksp.processing.*
import com.google.devtools.ksp.symbol.KSAnnotated
import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.google.devtools.ksp.symbol.KSFile
import com.pinterest.ktlint.cli.ruleset.core.api.RuleSetProviderV3
import com.pinterest.ktlint.rule.engine.api.Code
import com.pinterest.ktlint.rule.engine.api.EditorConfigDefaults
import com.pinterest.ktlint.rule.engine.api.KtLintRuleEngine
import com.squareup.kotlinpoet.FileSpec
import org.ec4j.core.EditorConfigLoader
import org.ec4j.core.Resource.Resources
import org.ktorm.ksp.annotation.Table
import org.ktorm.ksp.compiler.formatter.CodeFormatter
import org.ktorm.ksp.compiler.formatter.KtLintCodeFormatter
import org.ktorm.ksp.compiler.generator.FileGenerator
import org.ktorm.ksp.compiler.parser.MetadataParser
import org.ktorm.ksp.compiler.util.isValid
import org.ktorm.ksp.spi.TableMetadata
import java.util.*
import kotlin.reflect.jvm.jvmName

/**
* Ktorm KSP symbol processor provider.
*/
public class KtormProcessorProvider : SymbolProcessorProvider {
private val ktLintRuleEngine = KtLintRuleEngine(
ruleProviders = ServiceLoader
.load(RuleSetProviderV3::class.java, javaClass.classLoader)
.flatMap { it.getRuleProviders() }
.toSet(),
editorConfigDefaults = EditorConfigDefaults(
EditorConfigLoader.default_().load(
Resources.ofClassPath(javaClass.classLoader, "/ktorm-ksp-compiler/.editorconfig", Charsets.UTF_8)
)
)
)

override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
for (generator in FileGenerator.extCodeGenerators) {
Expand Down Expand Up @@ -81,32 +64,23 @@ public class KtormProcessorProvider : SymbolProcessorProvider {
// Generate file spec by kotlinpoet.
val fileSpec = FileGenerator.generate(table, environment)

// Beautify the generated code by ktlint.
val formattedCode = formatCode(fileSpec, environment.logger)
// Beautify the generated code.
val formattedCode = getCodeFormatter(environment).format(fileSpec.toString())

// Output the formatted code.
val dependencies = Dependencies(false, *table.getDependencyFiles().toTypedArray())
val file = environment.codeGenerator.createNewFile(dependencies, fileSpec.packageName, fileSpec.name)
file.writer(Charsets.UTF_8).use { it.write(formattedCode) }
}

private fun formatCode(fileSpec: FileSpec, logger: KSPLogger): String {
private fun getCodeFormatter(environment: SymbolProcessorEnvironment): CodeFormatter {
try {
// Manually fix some code styles before formatting.
val code = fileSpec.toString()
.replace(Regex("""\(\s*"""), "(")
.replace(Regex("""\s*\)"""), ")")
.replace(Regex(""",\s*"""), ", ")
.replace(Regex(""",\s*\)"""), ")")
.replace(Regex("""\s+get\(\)\s="""), " get() =")
.replace(Regex("""\s+=\s+"""), " = ")
.replace("import org.ktorm.ksp.`annotation`", "import org.ktorm.ksp.annotation")

return ktLintRuleEngine.format(Code.fromSnippet(code))
} catch (e: Exception) {
logger.exception(e)
return fileSpec.toString()
return KtLintCodeFormatter(environment)
} catch (_: ClassNotFoundException) {
} catch (_: NoClassDefFoundError) {
}

return CodeFormatter { code -> code }
}

private fun TableMetadata.getDependencyFiles(): List<KSFile> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.ktorm.ksp.compiler.formatter

/**
* Code formatter interface.
*/
internal fun interface CodeFormatter {

/**
* Format the generated code to the community recommended coding style.
*/
fun format(code: String): String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.ktorm.ksp.compiler.formatter

import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
import com.pinterest.ktlint.cli.ruleset.core.api.RuleSetProviderV3
import com.pinterest.ktlint.rule.engine.api.Code
import com.pinterest.ktlint.rule.engine.api.EditorConfigDefaults
import com.pinterest.ktlint.rule.engine.api.KtLintRuleEngine
import org.ec4j.core.EditorConfigLoader
import org.ec4j.core.Resource.Resources
import java.util.*

internal class KtLintCodeFormatter(val environment: SymbolProcessorEnvironment) : CodeFormatter {
private val ktLintRuleEngine = KtLintRuleEngine(
ruleProviders = ServiceLoader
.load(RuleSetProviderV3::class.java, javaClass.classLoader)
.flatMap { it.getRuleProviders() }
.toSet(),
editorConfigDefaults = EditorConfigDefaults(
EditorConfigLoader.default_().load(
Resources.ofClassPath(javaClass.classLoader, "/ktorm-ksp-compiler/.editorconfig", Charsets.UTF_8)
)
)
)

override fun format(code: String): String {
try {
// Manually fix some code styles before formatting.
val snippet = code
.replace(Regex("""\(\s*"""), "(")
.replace(Regex("""\s*\)"""), ")")
.replace(Regex(""",\s*"""), ", ")
.replace(Regex(""",\s*\)"""), ")")
.replace(Regex("""\s+get\(\)\s="""), " get() =")
.replace(Regex("""\s+=\s+"""), " = ")
.replace("import org.ktorm.ksp.`annotation`", "import org.ktorm.ksp.annotation")

return ktLintRuleEngine.format(Code.fromSnippet(snippet))
} catch (e: Throwable) {
environment.logger.exception(e)
return code
}
}
}

0 comments on commit b194c68

Please sign in to comment.