better result and error handling for importModule()

This commit is contained in:
Irmen de Jong 2021-10-12 23:54:48 +02:00
parent 9827ee97ad
commit 1c7c67060d
3 changed files with 38 additions and 36 deletions

View File

@ -181,7 +181,8 @@ fun parseImports(filepath: Path,
bf.program = programAst
val importer = ModuleImporter(programAst, compTarget.name, errors, libdirs)
importer.importModule(filepath)
val importedModuleResult = importer.importModule(filepath)
importedModuleResult.onFailure { throw it }
errors.report()
val importedFiles = programAst.modules

View File

@ -1,5 +1,8 @@
package prog8.compiler
import com.github.michaelbull.result.Err
import com.github.michaelbull.result.Ok
import com.github.michaelbull.result.Result
import prog8.ast.Module
import prog8.ast.Program
import prog8.ast.base.Position
@ -19,7 +22,7 @@ class ModuleImporter(private val program: Program,
private val libpaths: List<Path> = libdirs.map { Path(it) }
fun importModule(filePath: Path): Module {
fun importModule(filePath: Path): Result<Module, NoSuchFileException> {
val currentDir = Path("").absolute()
val searchIn = listOf(currentDir) + libpaths
val candidates = searchIn
@ -29,9 +32,9 @@ class ModuleImporter(private val program: Program,
.map { if (it.isAbsolute) it else Path(".", "$it") }
val srcPath = when (candidates.size) {
0 -> throw NoSuchFileException(
0 -> return Err(NoSuchFileException(
file = filePath.normalize().toFile(),
reason = "searched in $searchIn")
reason = "searched in $searchIn"))
1 -> candidates.first()
else -> candidates.first() // TODO: report error if more than 1 candidate?
}
@ -39,7 +42,7 @@ class ModuleImporter(private val program: Program,
val logMsg = "importing '${filePath.nameWithoutExtension}' (from file $srcPath)"
println(logMsg)
return importModule(SourceCode.fromPath(srcPath))
return Ok(importModule(SourceCode.fromPath(srcPath)))
}
fun importLibraryModule(name: String): Module? {

View File

@ -1,19 +1,22 @@
package prog8tests
import kotlin.test.*
import com.github.michaelbull.result.getErrorOrElse
import com.github.michaelbull.result.getOrElse
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.*
import org.hamcrest.core.Is
import org.junit.jupiter.api.*
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.Disabled
import prog8.ast.Program
import prog8.compiler.IErrorReporter
import prog8.compiler.ModuleImporter
import prog8.parser.ParseError
import prog8tests.helpers.*
import kotlin.io.path.*
import kotlin.test.assertContains
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertFalse
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@ -60,31 +63,26 @@ class TestModuleImporter {
val importer = makeImporter(null, dirRel.invariantSeparatorsPathString)
val srcPathRel = assumeNotExists(dirRel, "i_do_not_exist")
val srcPathAbs = srcPathRel.absolute()
assertFailsWith<NoSuchFileException> { importer.importModule(srcPathRel) }
.let {
assertThat(
".file should be normalized",
"${it.file}", equalTo("${it.file.normalize()}")
)
assertThat(
".file should point to specified path",
it.file.absolutePath, equalTo("${srcPathAbs.normalize()}")
)
}
val error1 = importer.importModule(srcPathRel).getErrorOrElse { fail("should have import error") }
assertThat(
".file should be normalized",
"${error1.file}", equalTo("${error1.file.normalize()}")
)
assertThat(
".file should point to specified path",
error1.file.absolutePath, equalTo("${srcPathAbs.normalize()}")
)
assertThat(program.modules.size, equalTo(1))
assertFailsWith<NoSuchFileException> { importer.importModule(srcPathAbs) }
.let {
assertThat(
".file should be normalized",
"${it.file}", equalTo("${it.file.normalize()}")
)
assertThat(
".file should point to specified path",
it.file.absolutePath, equalTo("${srcPathAbs.normalize()}")
)
}
val error2 = importer.importModule(srcPathAbs).getErrorOrElse { fail("should have import error") }
assertThat(
".file should be normalized",
"${error2.file}", equalTo("${error2.file.normalize()}")
)
assertThat(
".file should point to specified path",
error2.file.absolutePath, equalTo("${srcPathAbs.normalize()}")
)
assertThat(program.modules.size, equalTo(1))
}
@ -135,7 +133,7 @@ class TestModuleImporter {
val fileName = "simple_main.p8"
val path = assumeReadableFile(searchIn[0], fileName)
val module = importer.importModule(path.absolute())
val module = importer.importModule(path.absolute()).getOrElse { throw it }
assertThat(program.modules.size, equalTo(2))
assertContains(program.modules, module)
assertThat(module.program, equalTo(program))
@ -151,7 +149,7 @@ class TestModuleImporter {
val path = assumeReadableFile(searchIn[0], fileName)
assertThat("sanity check: path should NOT be absolute", path.isAbsolute, equalTo(false))
val module = importer.importModule(path)
val module = importer.importModule(path).getOrElse { throw it }
assertThat(program.modules.size, equalTo(2))
assertContains(program.modules, module)
assertThat(module.program, equalTo(program))
@ -167,7 +165,7 @@ class TestModuleImporter {
val path = Path(".", fileName)
assumeReadableFile(searchIn, path)
val module = importer.importModule(path)
val module = importer.importModule(path).getOrElse { throw it }
assertThat(program.modules.size, equalTo(2))
assertContains(program.modules, module)
assertThat(module.program, equalTo(program))