Improve support for olive programs inside packages

This commit is contained in:
Edwin Jakobs
2020-05-03 12:54:32 +02:00
parent de6095224a
commit f5aba87f50
3 changed files with 17 additions and 3 deletions

View File

@@ -18,6 +18,13 @@ fun ParserRuleContext.verbatimText(marginLeft: Int = 0, marginRight: Int = 0): S
return start.inputStream.getText(interval) return start.inputStream.getText(interval)
} }
class PackageExtractor() : KotlinParserBaseListener() {
var result: String? = null
override fun enterPackageHeader(ctx: KotlinParser.PackageHeaderContext) {
result = ctx.verbatimText()
}
}
class ImportsExtractor(val ruleNames: List<String>) : KotlinParserBaseListener() { class ImportsExtractor(val ruleNames: List<String>) : KotlinParserBaseListener() {
var result: String? = null var result: String? = null
@@ -30,6 +37,7 @@ class LambdaExtractor(val ruleNames: List<String>, val lambdaName: String) : Kot
fun RuleContext.named(): String { fun RuleContext.named(): String {
return ruleNames[this.ruleIndex] return ruleNames[this.ruleIndex]
} }
var result: String? = null var result: String? = null
override fun enterAnnotatedLambda(ctx: KotlinParser.AnnotatedLambdaContext?) { override fun enterAnnotatedLambda(ctx: KotlinParser.AnnotatedLambdaContext?) {
val puec = ctx!!.parent!!.parent!!.parent!! as KotlinParser.PostfixUnaryExpressionContext val puec = ctx!!.parent!!.parent!!.parent!! as KotlinParser.PostfixUnaryExpressionContext
@@ -42,7 +50,7 @@ class LambdaExtractor(val ruleNames: List<String>, val lambdaName: String) : Kot
} }
} }
class ProgramSource(val imports: String, val programLambda: String) class ProgramSource(val packageName: String?, val imports: String, val programLambda: String)
fun extractProgram(source: String, programIdentifier: String = "program"): ProgramSource { fun extractProgram(source: String, programIdentifier: String = "program"): ProgramSource {
val parser = KotlinParser(CommonTokenStream(KotlinLexer(CharStreams.fromString(source)))) val parser = KotlinParser(CommonTokenStream(KotlinLexer(CharStreams.fromString(source))))
@@ -50,10 +58,14 @@ fun extractProgram(source: String, programIdentifier: String = "program"): Progr
// val rules = parser.ruleNames.toList() // val rules = parser.ruleNames.toList()
// val pt = TreeUtils.toPrettyTree(root, rules) // val pt = TreeUtils.toPrettyTree(root, rules)
val ruleNames = parser.ruleNames.toList() val ruleNames = parser.ruleNames.toList()
val packageExtractor = PackageExtractor()
ParseTreeWalker.DEFAULT.walk(packageExtractor, root)
val importsExtractor = ImportsExtractor(ruleNames) val importsExtractor = ImportsExtractor(ruleNames)
ParseTreeWalker.DEFAULT.walk(importsExtractor, root) ParseTreeWalker.DEFAULT.walk(importsExtractor, root)
val lambdaExtractor = LambdaExtractor(ruleNames, programIdentifier) val lambdaExtractor = LambdaExtractor(ruleNames, programIdentifier)
ParseTreeWalker.DEFAULT.walk(lambdaExtractor, root) ParseTreeWalker.DEFAULT.walk(lambdaExtractor, root)
return ProgramSource(importsExtractor.result!!, lambdaExtractor.result!!) return ProgramSource(packageExtractor.result, importsExtractor.result?:"", lambdaExtractor.result?:"")
} }

View File

@@ -20,7 +20,7 @@ fun stackRootClassName(thread: Thread = Thread.currentThread(), sanitize: Boolea
} }
fun ApplicationBuilder.oliveProgram(init: OliveProgram.() -> Unit): OliveProgram { fun ApplicationBuilder.oliveProgram(init: OliveProgram.() -> Unit): OliveProgram {
val rootClassName = stackRootClassName(sanitize = true) val rootClassName = stackRootClassName(sanitize = true).split(".").last()
var sourceLocation = "src/main/kotlin/$rootClassName.kt" var sourceLocation = "src/main/kotlin/$rootClassName.kt"
val candidateFile = File(sourceLocation) val candidateFile = File(sourceLocation)

View File

@@ -4,7 +4,9 @@ import org.openrndr.extra.kotlinparser.ProgramSource
inline fun <reified T> generateScript(programSource: ProgramSource): String { inline fun <reified T> generateScript(programSource: ProgramSource): String {
val script = """ val script = """
@file:Suppress("UNUSED_LAMBDA_EXPRESSION") @file:Suppress("UNUSED_LAMBDA_EXPRESSION")
${programSource.packageName?:""}
import org.openrndr.extra.olive.OliveProgram import org.openrndr.extra.olive.OliveProgram
${programSource.imports} ${programSource.imports}