mirror of
https://github.com/irmen/prog8.git
synced 2024-11-19 11:32:17 +00:00
use new api for ast mods in unused code remover
This commit is contained in:
parent
1978a9815a
commit
edee70cf31
@ -1 +1 @@
|
||||
2.0
|
||||
2.1-SNAPSHOT
|
||||
|
@ -174,6 +174,7 @@ private fun optimizeAst(programAst: Program, errors: ErrorReporter) {
|
||||
|
||||
val remover = UnusedCodeRemover()
|
||||
remover.visit(programAst)
|
||||
remover.applyModifications()
|
||||
}
|
||||
|
||||
private fun postprocessAst(programAst: Program, errors: ErrorReporter, compilerOptions: CompilationOptions) {
|
||||
|
@ -1,55 +1,38 @@
|
||||
package prog8.optimizer
|
||||
|
||||
import prog8.ast.Module
|
||||
import prog8.ast.Node
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.processing.IAstModifyingVisitor
|
||||
import prog8.ast.processing.AstWalker
|
||||
import prog8.ast.processing.IAstModification
|
||||
import prog8.ast.statements.Block
|
||||
import prog8.ast.statements.Subroutine
|
||||
|
||||
|
||||
internal class UnusedCodeRemover: IAstModifyingVisitor {
|
||||
internal class UnusedCodeRemover: AstWalker() {
|
||||
|
||||
|
||||
override fun visit(program: Program) {
|
||||
override fun before(program: Program, parent: Node): Iterable<IAstModification> {
|
||||
val callgraph = CallGraph(program)
|
||||
val removals = mutableListOf<IAstModification>()
|
||||
|
||||
// remove all subroutines that aren't called, or are empty
|
||||
val removeSubroutines = mutableSetOf<Subroutine>()
|
||||
val entrypoint = program.entrypoint()
|
||||
program.modules.forEach {
|
||||
callgraph.forAllSubroutines(it) { sub ->
|
||||
if (sub !== entrypoint && !sub.keepAlways && (sub.calledBy.isEmpty() || (sub.containsNoCodeNorVars() && !sub.isAsmSubroutine)))
|
||||
removeSubroutines.add(sub)
|
||||
removals.add(IAstModification.Remove(sub, sub.definingScope() as Node))
|
||||
}
|
||||
}
|
||||
|
||||
if (removeSubroutines.isNotEmpty()) {
|
||||
removeSubroutines.forEach {
|
||||
it.definingScope().remove(it)
|
||||
}
|
||||
}
|
||||
|
||||
val removeBlocks = mutableSetOf<Block>()
|
||||
program.modules.flatMap { it.statements }.filterIsInstance<Block>().forEach { block ->
|
||||
if (block.containsNoCodeNorVars() && "force_output" !in block.options())
|
||||
removeBlocks.add(block)
|
||||
}
|
||||
|
||||
if (removeBlocks.isNotEmpty()) {
|
||||
removeBlocks.forEach { it.definingScope().remove(it) }
|
||||
removals.add(IAstModification.Remove(block, block.definingScope() as Node))
|
||||
}
|
||||
|
||||
// remove modules that are not imported, or are empty (unless it's a library modules)
|
||||
val removeModules = mutableSetOf<Module>()
|
||||
program.modules.forEach {
|
||||
if (!it.isLibraryModule && (it.importedBy.isEmpty() || it.containsNoCodeNorVars()))
|
||||
removeModules.add(it)
|
||||
removals.add(IAstModification.Remove(it, it.parent)) // TODO does removing modules work like this?
|
||||
}
|
||||
|
||||
if (removeModules.isNotEmpty()) {
|
||||
program.modules.removeAll(removeModules)
|
||||
}
|
||||
|
||||
super.visit(program)
|
||||
return removals
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user