Create module model
This commit is contained in:
125
src/main/kotlin/io/smnp/api/module/Module.kt
Normal file
125
src/main/kotlin/io/smnp/api/module/Module.kt
Normal file
@@ -0,0 +1,125 @@
|
||||
package io.smnp.api.module
|
||||
|
||||
import io.smnp.api.callable.Function
|
||||
import io.smnp.api.callable.Method
|
||||
import io.smnp.api.model.Value
|
||||
|
||||
class Module(
|
||||
val name: String,
|
||||
functions: List<Function> = emptyList(),
|
||||
methods: List<Method> = emptyList(),
|
||||
children: List<Module> = emptyList()
|
||||
) {
|
||||
private var parent: Module? = null
|
||||
private val children = mutableListOf<Module>()
|
||||
private val functions = functions.toMutableList()
|
||||
private val methods = methods.toMutableList()
|
||||
|
||||
init {
|
||||
children.forEach { addSubmodule(it) }
|
||||
}
|
||||
|
||||
fun addSubmodule(module: Module) {
|
||||
module.parent = this
|
||||
children.indexOfFirst { it.name == module.name }.let {
|
||||
if (it > -1) {
|
||||
children[it] = children[it].merge(module)
|
||||
} else {
|
||||
children.add(module)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun attachTo(module: Module) {
|
||||
module.addSubmodule(this)
|
||||
}
|
||||
|
||||
val canonicalName: String
|
||||
get() {
|
||||
val modules = mutableListOf(this)
|
||||
var par = parent
|
||||
while(par != null) {
|
||||
modules.add(par)
|
||||
par = par.parent
|
||||
}
|
||||
|
||||
return modules.reversed().joinToString(".") { it.name }
|
||||
}
|
||||
|
||||
fun merge(module: Module): Module {
|
||||
if(name != module.name) {
|
||||
return this
|
||||
}
|
||||
|
||||
val functions = functions + module.functions
|
||||
val methods = methods + module.methods
|
||||
|
||||
val commonAndMyChildren = children.map { child ->
|
||||
module.children.find { it.name == child.name }?.merge(child) ?: child
|
||||
}
|
||||
|
||||
val moduleChildren = module.children.filter { child -> children.none { it.name == child.name } }
|
||||
|
||||
return Module(name, functions, methods, (commonAndMyChildren + moduleChildren).toMutableList())
|
||||
}
|
||||
|
||||
fun findFunction(name: String): List<Function> {
|
||||
return functions.filter { it.name == name } + children.flatMap { it.findFunction(name) }
|
||||
}
|
||||
|
||||
fun findMethod(value: Value, name: String): List<Method> {
|
||||
return methods.filter { it.name == name && it.verifyType(value) } + children.flatMap { it.findMethod(value, name) }
|
||||
}
|
||||
|
||||
override fun toString() = name
|
||||
|
||||
fun pretty(printContent: Boolean = false, prefix: String = "", last: Boolean = true, first: Boolean = true) {
|
||||
var newPrefix = prefix
|
||||
var newLast = last
|
||||
|
||||
println(newPrefix + (if (first) "" else if (newLast) "└─ " else "├─ ") + name)
|
||||
newPrefix += if (newLast) " " else "│ "
|
||||
if(printContent) {
|
||||
val contentPrefix = newPrefix + if (children.isNotEmpty()) "|" else ""
|
||||
for ((index, function) in functions.withIndex()) {
|
||||
println(contentPrefix + (if (index == functions.size - 1 && methods.isEmpty()) "└ " else "├ ") + "${function.name}()")
|
||||
}
|
||||
|
||||
for ((index, method) in methods.withIndex()) {
|
||||
println(contentPrefix + (if (index == methods.size - 1) "└ " else "├ ") + "${method.typeMatcher}.${method.name}()")
|
||||
}
|
||||
}
|
||||
|
||||
for ((index, child) in children.withIndex()) {
|
||||
newLast = index == children.size - 1
|
||||
child.pretty(printContent, newPrefix, newLast, false)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun create(
|
||||
path: String,
|
||||
functions: List<Function> = emptyList(),
|
||||
methods: List<Method> = emptyList(),
|
||||
children: List<Module> = emptyList()
|
||||
): Module {
|
||||
val modules = path.split(".")
|
||||
if(modules.isEmpty()) {
|
||||
return Module(path, functions, methods, children)
|
||||
}
|
||||
|
||||
val root = modules.map { Module(it) }.reduceRight { m, n -> m.addSubmodule(n); m }
|
||||
|
||||
var youngest = root
|
||||
while(youngest.children.isNotEmpty()) {
|
||||
youngest = youngest.children[0]
|
||||
}
|
||||
|
||||
youngest.functions.addAll(functions)
|
||||
youngest.methods.addAll(methods)
|
||||
youngest.children.addAll(children)
|
||||
|
||||
return root
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,6 @@ abstract class Node(numberOfChildren: Int, val position: TokenPosition) {
|
||||
for ((index, child) in children.withIndex()) {
|
||||
newLast = index == children.size - 1
|
||||
child.pretty(newPrefix, newLast, false)
|
||||
//println(newPrefix + (if (newLast) "└ " else "├ ") + child) // todo move to atom nodes
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user