mirror of
https://github.com/irmen/prog8.git
synced 2024-11-03 13:07:54 +00:00
92 lines
3.4 KiB
Kotlin
92 lines
3.4 KiB
Kotlin
|
package prog8tests
|
||
|
|
||
|
import org.junit.jupiter.api.Test
|
||
|
import org.junit.jupiter.api.TestInstance
|
||
|
import prog8.ast.statements.Block
|
||
|
import prog8.ast.statements.Subroutine
|
||
|
import prog8.compiler.target.C64Target
|
||
|
import prog8.optimizer.CallGraph
|
||
|
import prog8tests.helpers.assertSuccess
|
||
|
import prog8tests.helpers.compileText
|
||
|
import kotlin.test.assertEquals
|
||
|
import kotlin.test.assertFalse
|
||
|
import kotlin.test.assertTrue
|
||
|
|
||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||
|
class TestCallgraph {
|
||
|
@Test
|
||
|
fun testGraphForEmptySubs() {
|
||
|
val sourcecode = """
|
||
|
%import string
|
||
|
main {
|
||
|
sub start() {
|
||
|
}
|
||
|
sub empty() {
|
||
|
}
|
||
|
}
|
||
|
"""
|
||
|
val result = compileText(C64Target, false, sourcecode).assertSuccess()
|
||
|
val graph = CallGraph(result.programAst)
|
||
|
|
||
|
assertEquals(1, graph.imports.size)
|
||
|
assertEquals(1, graph.importedBy.size)
|
||
|
val toplevelModule = result.programAst.toplevelModule
|
||
|
val importedModule = graph.imports.getValue(toplevelModule).single()
|
||
|
assertEquals("string", importedModule.name)
|
||
|
val importedBy = graph.importedBy.getValue(importedModule).single()
|
||
|
assertTrue(importedBy.name.startsWith("on_the_fly_test"))
|
||
|
|
||
|
assertFalse(graph.unused(toplevelModule))
|
||
|
assertFalse(graph.unused(importedModule))
|
||
|
|
||
|
val mainBlock = toplevelModule.statements.filterIsInstance<Block>().single()
|
||
|
for(stmt in mainBlock.statements) {
|
||
|
val sub = stmt as Subroutine
|
||
|
assertFalse(sub in graph.calls)
|
||
|
assertFalse(sub in graph.calledBy)
|
||
|
|
||
|
if(sub === result.programAst.entrypoint)
|
||
|
assertFalse(graph.unused(sub), "start() should always be marked as used to avoid having it removed")
|
||
|
else
|
||
|
assertTrue(graph.unused(sub))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Test
|
||
|
fun testGraphForEmptyButReferencedSub() {
|
||
|
val sourcecode = """
|
||
|
%import string
|
||
|
main {
|
||
|
sub start() {
|
||
|
uword xx = &empty
|
||
|
xx++
|
||
|
}
|
||
|
sub empty() {
|
||
|
}
|
||
|
}
|
||
|
"""
|
||
|
val result = compileText(C64Target, false, sourcecode).assertSuccess()
|
||
|
val graph = CallGraph(result.programAst)
|
||
|
|
||
|
assertEquals(1, graph.imports.size)
|
||
|
assertEquals(1, graph.importedBy.size)
|
||
|
val toplevelModule = result.programAst.toplevelModule
|
||
|
val importedModule = graph.imports.getValue(toplevelModule).single()
|
||
|
assertEquals("string", importedModule.name)
|
||
|
val importedBy = graph.importedBy.getValue(importedModule).single()
|
||
|
assertTrue(importedBy.name.startsWith("on_the_fly_test"))
|
||
|
|
||
|
assertFalse(graph.unused(toplevelModule))
|
||
|
assertFalse(graph.unused(importedModule))
|
||
|
|
||
|
val mainBlock = toplevelModule.statements.filterIsInstance<Block>().single()
|
||
|
val startSub = mainBlock.statements.filterIsInstance<Subroutine>().single{it.name=="start"}
|
||
|
val emptySub = mainBlock.statements.filterIsInstance<Subroutine>().single{it.name=="empty"}
|
||
|
|
||
|
assertTrue(startSub in graph.calls, "start 'calls' (references) empty")
|
||
|
assertFalse(emptySub in graph.calls, "empty doesn't call anything")
|
||
|
assertTrue(emptySub in graph.calledBy, "empty gets 'called'")
|
||
|
assertFalse(startSub in graph.calledBy, "start doesn't get called (except as entrypoint ofc.)")
|
||
|
}
|
||
|
}
|