From a1561c33bb2d5745cfeb2a1ad1a2a14e7e2a3e3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Przemys=C5=82aw=20Pluta?= Date: Mon, 9 Mar 2020 17:28:37 +0100 Subject: [PATCH] Create module model --- src/main/kotlin/io/smnp/api/module/Module.kt | 125 ++++++++++++++++++ .../kotlin/io/smnp/dsl/ast/model/node/Node.kt | 1 - 2 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/io/smnp/api/module/Module.kt diff --git a/src/main/kotlin/io/smnp/api/module/Module.kt b/src/main/kotlin/io/smnp/api/module/Module.kt new file mode 100644 index 0000000..5bc2b38 --- /dev/null +++ b/src/main/kotlin/io/smnp/api/module/Module.kt @@ -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 = emptyList(), + methods: List = emptyList(), + children: List = emptyList() +) { + private var parent: Module? = null + private val children = mutableListOf() + 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 { + return functions.filter { it.name == name } + children.flatMap { it.findFunction(name) } + } + + fun findMethod(value: Value, name: String): List { + 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 = emptyList(), + methods: List = emptyList(), + children: List = 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 + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/io/smnp/dsl/ast/model/node/Node.kt b/src/main/kotlin/io/smnp/dsl/ast/model/node/Node.kt index 8bb8772..9dbfd35 100644 --- a/src/main/kotlin/io/smnp/dsl/ast/model/node/Node.kt +++ b/src/main/kotlin/io/smnp/dsl/ast/model/node/Node.kt @@ -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 } }