mirror of
https://github.com/irmen/prog8.git
synced 2025-01-08 22:32:06 +00:00
avoid re-reading all source files when sourcelines are requested in the asm
This commit is contained in:
parent
512ddd1694
commit
131d5ceb4f
60
codeCore/src/prog8/code/source/ImportFileSystem.kt
Normal file
60
codeCore/src/prog8/code/source/ImportFileSystem.kt
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package prog8.code.source
|
||||||
|
|
||||||
|
import prog8.code.core.Position
|
||||||
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.Path
|
||||||
|
|
||||||
|
|
||||||
|
// Resource caching "filesystem".
|
||||||
|
// Note that it leaves the decision to load a resource or an actual disk file to the caller.
|
||||||
|
|
||||||
|
object ImportFileSystem {
|
||||||
|
fun getFile(path: Path): SourceCode {
|
||||||
|
val cached = cache[path.toString()]
|
||||||
|
if (cached != null) return cached
|
||||||
|
val file = SourceCode.File(path)
|
||||||
|
cache[path.toString()] = file
|
||||||
|
return file
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getResource(name: String): SourceCode {
|
||||||
|
val cached = cache[name]
|
||||||
|
if (cached != null) return cached
|
||||||
|
val resource = SourceCode.Resource(name)
|
||||||
|
cache[name] = resource
|
||||||
|
return resource
|
||||||
|
}
|
||||||
|
|
||||||
|
fun retrieveSourceLine(position: Position): String {
|
||||||
|
if(SourceCode.isLibraryResource(position.file)) {
|
||||||
|
val cached = cache[SourceCode.withoutPrefix(position.file)]
|
||||||
|
if(cached != null)
|
||||||
|
return getLine(cached, position.line)
|
||||||
|
}
|
||||||
|
val cached = cache[position.file]
|
||||||
|
if(cached != null)
|
||||||
|
return getLine(cached, position.line)
|
||||||
|
val path = Path(position.file).toAbsolutePath().normalize()
|
||||||
|
val cached2 = cache[path.toString()]
|
||||||
|
if(cached2 != null)
|
||||||
|
return getLine(cached2, position.line)
|
||||||
|
throw NoSuchElementException("cannot get source line $position")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getLine(code: SourceCode, lineIndex: Int): String {
|
||||||
|
var spans = lineSpanCache[code]
|
||||||
|
if(spans==null) {
|
||||||
|
val lineSpans = Regex("^", RegexOption.MULTILINE).findAll(code.text).map { it.range.first }
|
||||||
|
val ends = lineSpans.drop(1) + code.text.length
|
||||||
|
spans = lineSpans.zip(ends).map { (start, end) -> LineSpan(start, end) }.toList().toTypedArray()
|
||||||
|
lineSpanCache[code] = spans
|
||||||
|
}
|
||||||
|
val span = spans[lineIndex - 1]
|
||||||
|
return code.text.substring(span.start, span.end).trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
private class LineSpan(val start: Int, val end: Int)
|
||||||
|
|
||||||
|
private val cache = mutableMapOf<String, SourceCode>()
|
||||||
|
private val lineSpanCache = mutableMapOf<SourceCode, Array<LineSpan>>()
|
||||||
|
}
|
@ -82,12 +82,13 @@ sealed class SourceCode {
|
|||||||
/**
|
/**
|
||||||
* Get [SourceCode] from the file represented by the specified Path.
|
* Get [SourceCode] from the file represented by the specified Path.
|
||||||
* This immediately reads the file fully into memory.
|
* This immediately reads the file fully into memory.
|
||||||
|
* You can only get an instance of this via the ImportFileSystem object.
|
||||||
*
|
*
|
||||||
* [origin] will be the given path in absolute and normalized form.
|
* [origin] will be the given path in absolute and normalized form.
|
||||||
* @throws NoSuchFileException if the file does not exist
|
* @throws NoSuchFileException if the file does not exist
|
||||||
* @throws FileSystemException if the file cannot be read
|
* @throws FileSystemException if the file cannot be read
|
||||||
*/
|
*/
|
||||||
class File(path: Path): SourceCode() {
|
internal class File(path: Path): SourceCode() {
|
||||||
override val text: String
|
override val text: String
|
||||||
override val origin: String
|
override val origin: String
|
||||||
override val name: String
|
override val name: String
|
||||||
@ -111,8 +112,9 @@ sealed class SourceCode {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* [origin]: `library:/x/y/z.p8` for a given `pathString` of "x/y/z.p8"
|
* [origin]: `library:/x/y/z.p8` for a given `pathString` of "x/y/z.p8"
|
||||||
|
* You can only get an instance of this via the ImportFileSystem object.
|
||||||
*/
|
*/
|
||||||
class Resource(pathString: String): SourceCode() {
|
internal class Resource(pathString: String): SourceCode() {
|
||||||
private val normalized = "/" + Path(pathString).normalize().toMutableList().joinToString("/")
|
private val normalized = "/" + Path(pathString).normalize().toMutableList().joinToString("/")
|
||||||
|
|
||||||
override val isFromResources = true
|
override val isFromResources = true
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
package prog8.code.source
|
|
||||||
|
|
||||||
import prog8.code.core.Position
|
|
||||||
import kotlin.io.path.Path
|
|
||||||
|
|
||||||
object SourceLineCache {
|
|
||||||
private val cache = mutableMapOf<String, List<String>>()
|
|
||||||
|
|
||||||
private fun getCachedFile(file: String): List<String> {
|
|
||||||
val existing = cache[file]
|
|
||||||
if(existing!=null)
|
|
||||||
return existing
|
|
||||||
if (SourceCode.isRegularFilesystemPath(file)) {
|
|
||||||
val source = SourceCode.File(Path(file))
|
|
||||||
cache[file] = source.text.split('\n', '\r').map { it.trim() }
|
|
||||||
return cache.getValue(file)
|
|
||||||
} else if(SourceCode.isLibraryResource(file)) {
|
|
||||||
val source = SourceCode.Resource(SourceCode.withoutPrefix(file))
|
|
||||||
cache[file] = source.text.split('\n', '\r').map { it.trim()}
|
|
||||||
return cache.getValue(file)
|
|
||||||
}
|
|
||||||
return emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun retrieveLine(position: Position): String? {
|
|
||||||
if (position.line>0) {
|
|
||||||
val lines = getCachedFile(position.file)
|
|
||||||
if(lines.isNotEmpty())
|
|
||||||
return lines[position.line-1]
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,8 +7,8 @@ import prog8.code.SymbolTable
|
|||||||
import prog8.code.SymbolTableMaker
|
import prog8.code.SymbolTableMaker
|
||||||
import prog8.code.ast.*
|
import prog8.code.ast.*
|
||||||
import prog8.code.core.*
|
import prog8.code.core.*
|
||||||
|
import prog8.code.source.ImportFileSystem
|
||||||
import prog8.code.source.SourceCode
|
import prog8.code.source.SourceCode
|
||||||
import prog8.code.source.SourceLineCache
|
|
||||||
import prog8.code.target.Cx16Target
|
import prog8.code.target.Cx16Target
|
||||||
import prog8.codegen.cpu6502.assignment.*
|
import prog8.codegen.cpu6502.assignment.*
|
||||||
import kotlin.io.path.Path
|
import kotlin.io.path.Path
|
||||||
@ -337,11 +337,8 @@ class AsmGen6502Internal (
|
|||||||
|
|
||||||
lastSourceLineNumber = node.position.line
|
lastSourceLineNumber = node.position.line
|
||||||
val srcComment = "\t; source: ${node.position.file}:${node.position.line}"
|
val srcComment = "\t; source: ${node.position.file}:${node.position.line}"
|
||||||
val line = SourceLineCache.retrieveLine(node.position)
|
val line = ImportFileSystem.retrieveSourceLine(node.position)
|
||||||
if(line==null)
|
out("$srcComment $line", false)
|
||||||
out(srcComment, false)
|
|
||||||
else
|
|
||||||
out("$srcComment $line", false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun out(str: String, splitlines: Boolean = true) {
|
internal fun out(str: String, splitlines: Boolean = true) {
|
||||||
|
@ -8,6 +8,7 @@ import prog8.ast.statements.Directive
|
|||||||
import prog8.ast.statements.DirectiveArg
|
import prog8.ast.statements.DirectiveArg
|
||||||
import prog8.code.core.IErrorReporter
|
import prog8.code.core.IErrorReporter
|
||||||
import prog8.code.core.Position
|
import prog8.code.core.Position
|
||||||
|
import prog8.code.source.ImportFileSystem
|
||||||
import prog8.code.source.SourceCode
|
import prog8.code.source.SourceCode
|
||||||
import prog8.parser.Prog8Parser
|
import prog8.parser.Prog8Parser
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@ -32,7 +33,7 @@ class ModuleImporter(private val program: Program,
|
|||||||
if(programPath.exists()) {
|
if(programPath.exists()) {
|
||||||
println("Compiling program ${Path("").absolute().relativize(programPath)}")
|
println("Compiling program ${Path("").absolute().relativize(programPath)}")
|
||||||
println("Compiler target: $compilationTargetName")
|
println("Compiler target: $compilationTargetName")
|
||||||
val source = SourceCode.File(programPath)
|
val source = ImportFileSystem.getFile(programPath)
|
||||||
return Ok(importModule(source))
|
return Ok(importModule(source))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,8 +123,8 @@ class ModuleImporter(private val program: Program,
|
|||||||
|
|
||||||
private fun getModuleFromResource(name: String, compilationTargetName: String): Result<SourceCode, NoSuchFileException> {
|
private fun getModuleFromResource(name: String, compilationTargetName: String): Result<SourceCode, NoSuchFileException> {
|
||||||
val result =
|
val result =
|
||||||
runCatching { SourceCode.Resource("/prog8lib/$compilationTargetName/$name") }
|
runCatching { ImportFileSystem.getResource("/prog8lib/$compilationTargetName/$name") }
|
||||||
.orElse { runCatching { SourceCode.Resource("/prog8lib/$name") } }
|
.orElse { runCatching { ImportFileSystem.getResource("/prog8lib/$name") } }
|
||||||
|
|
||||||
return result.mapError { NoSuchFileException(File(name)) }
|
return result.mapError { NoSuchFileException(File(name)) }
|
||||||
}
|
}
|
||||||
@ -140,7 +141,7 @@ class ModuleImporter(private val program: Program,
|
|||||||
|
|
||||||
locations.forEach {
|
locations.forEach {
|
||||||
try {
|
try {
|
||||||
return Ok(SourceCode.File(it.resolve(fileName)))
|
return Ok(ImportFileSystem.getFile(it.resolve(fileName)))
|
||||||
} catch (_: NoSuchFileException) {
|
} catch (_: NoSuchFileException) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import prog8.ast.expressions.*
|
|||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.code.ast.*
|
import prog8.code.ast.*
|
||||||
import prog8.code.core.*
|
import prog8.code.core.*
|
||||||
|
import prog8.code.source.ImportFileSystem
|
||||||
import prog8.code.source.SourceCode
|
import prog8.code.source.SourceCode
|
||||||
import prog8.compiler.builtinFunctionReturnType
|
import prog8.compiler.builtinFunctionReturnType
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@ -769,14 +770,14 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
|
|||||||
return if (SourceCode.isLibraryResource(filename)) {
|
return if (SourceCode.isLibraryResource(filename)) {
|
||||||
return com.github.michaelbull.result.runCatching {
|
return com.github.michaelbull.result.runCatching {
|
||||||
val physFilename = SourceCode.withoutPrefix(filename)
|
val physFilename = SourceCode.withoutPrefix(filename)
|
||||||
SourceCode.Resource("/prog8lib/$physFilename").text
|
ImportFileSystem.getResource("/prog8lib/$physFilename").text
|
||||||
}.mapError { NoSuchFileException(File(filename)) }
|
}.mapError { NoSuchFileException(File(filename)) }
|
||||||
} else {
|
} else {
|
||||||
val sib = Path(source.origin).resolveSibling(filename)
|
val sib = Path(source.origin).resolveSibling(filename)
|
||||||
if (sib.isRegularFile())
|
if (sib.isRegularFile())
|
||||||
Ok(SourceCode.File(sib).text)
|
Ok(ImportFileSystem.getFile(sib).text)
|
||||||
else
|
else
|
||||||
Ok(SourceCode.File(Path(filename)).text)
|
Ok(ImportFileSystem.getFile(Path(filename)).text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ import prog8.ast.Program
|
|||||||
import prog8.ast.expressions.*
|
import prog8.ast.expressions.*
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.code.core.*
|
import prog8.code.core.*
|
||||||
|
import prog8.code.source.ImportFileSystem
|
||||||
import prog8.code.source.SourceCode
|
import prog8.code.source.SourceCode
|
||||||
import prog8.code.target.C64Target
|
import prog8.code.target.C64Target
|
||||||
import prog8.code.target.VMTarget
|
import prog8.code.target.VMTarget
|
||||||
@ -191,7 +192,7 @@ class TestProg8Parser: FunSpec( {
|
|||||||
|
|
||||||
test("from an empty file should result in empty Module") {
|
test("from an empty file should result in empty Module") {
|
||||||
val path = assumeReadableFile(fixturesDir, "ast_empty.p8")
|
val path = assumeReadableFile(fixturesDir, "ast_empty.p8")
|
||||||
val module = parseModule(SourceCode.File(path))
|
val module = parseModule(ImportFileSystem.getFile(path))
|
||||||
module.statements.size shouldBe 0
|
module.statements.size shouldBe 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,7 +211,7 @@ class TestProg8Parser: FunSpec( {
|
|||||||
|
|
||||||
test("parsed from a file") {
|
test("parsed from a file") {
|
||||||
val path = assumeReadableFile(fixturesDir, "ast_simple_main.p8")
|
val path = assumeReadableFile(fixturesDir, "ast_simple_main.p8")
|
||||||
val module = parseModule(SourceCode.File(path))
|
val module = parseModule(ImportFileSystem.getFile(path))
|
||||||
module.name shouldBe path.nameWithoutExtension
|
module.name shouldBe path.nameWithoutExtension
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -274,7 +275,7 @@ class TestProg8Parser: FunSpec( {
|
|||||||
test("in ParseError from bad file source code") {
|
test("in ParseError from bad file source code") {
|
||||||
val path = assumeReadableFile(fixturesDir, "ast_file_with_syntax_error.p8")
|
val path = assumeReadableFile(fixturesDir, "ast_file_with_syntax_error.p8")
|
||||||
|
|
||||||
val e = shouldThrow<ParseError> { parseModule(SourceCode.File(path)) }
|
val e = shouldThrow<ParseError> { parseModule(ImportFileSystem.getFile(path)) }
|
||||||
assertPosition(e.position, SourceCode.relative(path).toString(), 2, 4)
|
assertPosition(e.position, SourceCode.relative(path).toString(), 2, 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,14 +290,14 @@ class TestProg8Parser: FunSpec( {
|
|||||||
|
|
||||||
test("of Module parsed from a file") {
|
test("of Module parsed from a file") {
|
||||||
val path = assumeReadableFile(fixturesDir, "ast_simple_main.p8")
|
val path = assumeReadableFile(fixturesDir, "ast_simple_main.p8")
|
||||||
val module = parseModule(SourceCode.File(path))
|
val module = parseModule(ImportFileSystem.getFile(path))
|
||||||
assertPositionOf(module, SourceCode.relative(path).toString(), 1, 0)
|
assertPositionOf(module, SourceCode.relative(path).toString(), 1, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
test("of non-root Nodes parsed from file") {
|
test("of non-root Nodes parsed from file") {
|
||||||
val path = assumeReadableFile(fixturesDir, "ast_simple_main.p8")
|
val path = assumeReadableFile(fixturesDir, "ast_simple_main.p8")
|
||||||
|
|
||||||
val module = parseModule(SourceCode.File(path))
|
val module = parseModule(ImportFileSystem.getFile(path))
|
||||||
val mpf = module.position.file
|
val mpf = module.position.file
|
||||||
assertPositionOf(module, SourceCode.relative(path).toString(), 1, 0)
|
assertPositionOf(module, SourceCode.relative(path).toString(), 1, 0)
|
||||||
val mainBlock = module.statements.filterIsInstance<Block>()[0]
|
val mainBlock = module.statements.filterIsInstance<Block>()[0]
|
||||||
@ -359,7 +360,7 @@ class TestProg8Parser: FunSpec( {
|
|||||||
|
|
||||||
test("isn't absolute for filesystem paths") {
|
test("isn't absolute for filesystem paths") {
|
||||||
val path = assumeReadableFile(fixturesDir, "ast_simple_main.p8")
|
val path = assumeReadableFile(fixturesDir, "ast_simple_main.p8")
|
||||||
val module = parseModule(SourceCode.File(path))
|
val module = parseModule(ImportFileSystem.getFile(path))
|
||||||
assertSomethingForAllNodes(module) {
|
assertSomethingForAllNodes(module) {
|
||||||
Path(it.position.file).isAbsolute shouldBe false
|
Path(it.position.file).isAbsolute shouldBe false
|
||||||
Path(it.position.file).isRegularFile() shouldBe true
|
Path(it.position.file).isRegularFile() shouldBe true
|
||||||
@ -385,7 +386,7 @@ class TestProg8Parser: FunSpec( {
|
|||||||
|
|
||||||
test("is library prefixed path for resources")
|
test("is library prefixed path for resources")
|
||||||
{
|
{
|
||||||
val resource = SourceCode.Resource("prog8lib/math.p8")
|
val resource = ImportFileSystem.getResource("prog8lib/math.p8")
|
||||||
val module = parseModule(resource)
|
val module = parseModule(resource)
|
||||||
assertSomethingForAllNodes(module) {
|
assertSomethingForAllNodes(module) {
|
||||||
SourceCode.isLibraryResource(it.position.file) shouldBe true
|
SourceCode.isLibraryResource(it.position.file) shouldBe true
|
||||||
|
@ -5,6 +5,7 @@ import io.kotest.core.spec.style.AnnotationSpec
|
|||||||
import io.kotest.matchers.shouldBe
|
import io.kotest.matchers.shouldBe
|
||||||
import io.kotest.matchers.shouldNotBe
|
import io.kotest.matchers.shouldNotBe
|
||||||
import io.kotest.matchers.string.shouldContain
|
import io.kotest.matchers.string.shouldContain
|
||||||
|
import prog8.code.source.ImportFileSystem
|
||||||
import prog8.code.source.SourceCode
|
import prog8.code.source.SourceCode
|
||||||
import prog8tests.helpers.*
|
import prog8tests.helpers.*
|
||||||
import kotlin.io.path.Path
|
import kotlin.io.path.Path
|
||||||
@ -23,7 +24,7 @@ class TestSourceCode: AnnotationSpec() {
|
|||||||
src.text shouldBe text
|
src.text shouldBe text
|
||||||
src.isFromResources shouldBe false
|
src.isFromResources shouldBe false
|
||||||
src.isFromFilesystem shouldBe false
|
src.isFromFilesystem shouldBe false
|
||||||
src.toString().startsWith("prog8.code.core.SourceCode") shouldBe true
|
src.toString().startsWith(SourceCode::class.qualifiedName!!) shouldBe true
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -38,19 +39,19 @@ class TestSourceCode: AnnotationSpec() {
|
|||||||
fun testFromPathWithNonExistingPath() {
|
fun testFromPathWithNonExistingPath() {
|
||||||
val filename = "i_do_not_exist.p8"
|
val filename = "i_do_not_exist.p8"
|
||||||
val path = assumeNotExists(fixturesDir, filename)
|
val path = assumeNotExists(fixturesDir, filename)
|
||||||
shouldThrow<NoSuchFileException> { SourceCode.File(path) }
|
shouldThrow<NoSuchFileException> { ImportFileSystem.getFile(path) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testFromPathWithMissingExtension_p8() {
|
fun testFromPathWithMissingExtension_p8() {
|
||||||
val pathWithoutExt = assumeNotExists(fixturesDir,"simple_main")
|
val pathWithoutExt = assumeNotExists(fixturesDir,"simple_main")
|
||||||
assumeReadableFile(fixturesDir,"ast_simple_main.p8")
|
assumeReadableFile(fixturesDir,"ast_simple_main.p8")
|
||||||
shouldThrow<NoSuchFileException> { SourceCode.File(pathWithoutExt) }
|
shouldThrow<NoSuchFileException> { ImportFileSystem.getFile(pathWithoutExt) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testFromPathWithDirectory() {
|
fun testFromPathWithDirectory() {
|
||||||
shouldThrow<FileSystemException> { SourceCode.File(fixturesDir) }
|
shouldThrow<FileSystemException> { ImportFileSystem.getFile(fixturesDir) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ class TestSourceCode: AnnotationSpec() {
|
|||||||
fun testFromPathWithExistingPath() {
|
fun testFromPathWithExistingPath() {
|
||||||
val filename = "ast_simple_main.p8"
|
val filename = "ast_simple_main.p8"
|
||||||
val path = assumeReadableFile(fixturesDir, filename)
|
val path = assumeReadableFile(fixturesDir, filename)
|
||||||
val src = SourceCode.File(path)
|
val src = ImportFileSystem.getFile(path)
|
||||||
val expectedOrigin = SourceCode.relative(path).toString()
|
val expectedOrigin = SourceCode.relative(path).toString()
|
||||||
src.origin shouldBe expectedOrigin
|
src.origin shouldBe expectedOrigin
|
||||||
src.text shouldBe normalizeLineEndings(path.toFile().readText())
|
src.text shouldBe normalizeLineEndings(path.toFile().readText())
|
||||||
@ -76,7 +77,7 @@ class TestSourceCode: AnnotationSpec() {
|
|||||||
val filePath = outputDir.resolve("on_the_fly_test_" + text.hashCode().toUInt().toString(16) + ".p8")
|
val filePath = outputDir.resolve("on_the_fly_test_" + text.hashCode().toUInt().toString(16) + ".p8")
|
||||||
filePath.toFile().writeText(text)
|
filePath.toFile().writeText(text)
|
||||||
val path = assumeReadableFile(fixturesDir, filePath)
|
val path = assumeReadableFile(fixturesDir, filePath)
|
||||||
val src = SourceCode.File(path)
|
val src = ImportFileSystem.getFile(path)
|
||||||
src.text shouldNotBe path.toFile().readText() // should be normalized!
|
src.text shouldNotBe path.toFile().readText() // should be normalized!
|
||||||
src.text.split('\r', '\n').size shouldBe 5
|
src.text.split('\r', '\n').size shouldBe 5
|
||||||
}
|
}
|
||||||
@ -86,7 +87,7 @@ class TestSourceCode: AnnotationSpec() {
|
|||||||
val filename = "ast_simple_main.p8"
|
val filename = "ast_simple_main.p8"
|
||||||
val path = Path(".", "test", "..", "test", "fixtures", filename)
|
val path = Path(".", "test", "..", "test", "fixtures", filename)
|
||||||
val srcFile = assumeReadableFile(path).toFile()
|
val srcFile = assumeReadableFile(path).toFile()
|
||||||
val src = SourceCode.File(path)
|
val src = ImportFileSystem.getFile(path)
|
||||||
val expectedOrigin = SourceCode.relative(path).toString()
|
val expectedOrigin = SourceCode.relative(path).toString()
|
||||||
src.origin shouldBe expectedOrigin
|
src.origin shouldBe expectedOrigin
|
||||||
src.text shouldBe normalizeLineEndings(srcFile.readText())
|
src.text shouldBe normalizeLineEndings(srcFile.readText())
|
||||||
@ -96,7 +97,7 @@ class TestSourceCode: AnnotationSpec() {
|
|||||||
fun testFromResourcesWithExistingP8File_withoutLeadingSlash() {
|
fun testFromResourcesWithExistingP8File_withoutLeadingSlash() {
|
||||||
val pathString = "prog8lib/math.p8"
|
val pathString = "prog8lib/math.p8"
|
||||||
val srcFile = assumeReadableFile(resourcesDir, pathString).toFile()
|
val srcFile = assumeReadableFile(resourcesDir, pathString).toFile()
|
||||||
val src = SourceCode.Resource(pathString)
|
val src = ImportFileSystem.getResource(pathString)
|
||||||
|
|
||||||
src.origin shouldBe "library:/$pathString"
|
src.origin shouldBe "library:/$pathString"
|
||||||
src.text shouldBe normalizeLineEndings(srcFile.readText())
|
src.text shouldBe normalizeLineEndings(srcFile.readText())
|
||||||
@ -108,7 +109,7 @@ class TestSourceCode: AnnotationSpec() {
|
|||||||
fun testFromResourcesWithExistingP8File_withLeadingSlash() {
|
fun testFromResourcesWithExistingP8File_withLeadingSlash() {
|
||||||
val pathString = "/prog8lib/math.p8"
|
val pathString = "/prog8lib/math.p8"
|
||||||
val srcFile = assumeReadableFile(resourcesDir, pathString.substring(1)).toFile()
|
val srcFile = assumeReadableFile(resourcesDir, pathString.substring(1)).toFile()
|
||||||
val src = SourceCode.Resource(pathString)
|
val src = ImportFileSystem.getResource(pathString)
|
||||||
|
|
||||||
src.origin shouldBe "library:$pathString"
|
src.origin shouldBe "library:$pathString"
|
||||||
src.text shouldBe normalizeLineEndings(srcFile.readText())
|
src.text shouldBe normalizeLineEndings(srcFile.readText())
|
||||||
@ -118,7 +119,7 @@ class TestSourceCode: AnnotationSpec() {
|
|||||||
fun testFromResourcesWithExistingAsmFile_withoutLeadingSlash() {
|
fun testFromResourcesWithExistingAsmFile_withoutLeadingSlash() {
|
||||||
val pathString = "prog8lib/math.asm"
|
val pathString = "prog8lib/math.asm"
|
||||||
val srcFile = assumeReadableFile(resourcesDir, pathString).toFile()
|
val srcFile = assumeReadableFile(resourcesDir, pathString).toFile()
|
||||||
val src = SourceCode.Resource(pathString)
|
val src = ImportFileSystem.getResource(pathString)
|
||||||
|
|
||||||
src.origin shouldBe "library:/$pathString"
|
src.origin shouldBe "library:/$pathString"
|
||||||
src.text shouldBe normalizeLineEndings(srcFile.readText())
|
src.text shouldBe normalizeLineEndings(srcFile.readText())
|
||||||
@ -129,7 +130,7 @@ class TestSourceCode: AnnotationSpec() {
|
|||||||
fun testFromResourcesWithExistingAsmFile_withLeadingSlash() {
|
fun testFromResourcesWithExistingAsmFile_withLeadingSlash() {
|
||||||
val pathString = "/prog8lib/math.asm"
|
val pathString = "/prog8lib/math.asm"
|
||||||
val srcFile = assumeReadableFile(resourcesDir, pathString.substring(1)).toFile()
|
val srcFile = assumeReadableFile(resourcesDir, pathString.substring(1)).toFile()
|
||||||
val src = SourceCode.Resource(pathString)
|
val src = ImportFileSystem.getResource(pathString)
|
||||||
|
|
||||||
src.origin shouldBe "library:$pathString"
|
src.origin shouldBe "library:$pathString"
|
||||||
src.text shouldBe normalizeLineEndings(srcFile.readText())
|
src.text shouldBe normalizeLineEndings(srcFile.readText())
|
||||||
@ -139,7 +140,7 @@ class TestSourceCode: AnnotationSpec() {
|
|||||||
fun testFromResourcesWithNonNormalizedPath() {
|
fun testFromResourcesWithNonNormalizedPath() {
|
||||||
val pathString = "/prog8lib/../prog8lib/math.p8"
|
val pathString = "/prog8lib/../prog8lib/math.p8"
|
||||||
val srcFile = assumeReadableFile(resourcesDir, pathString.substring(1)).toFile()
|
val srcFile = assumeReadableFile(resourcesDir, pathString.substring(1)).toFile()
|
||||||
val src = SourceCode.Resource(pathString)
|
val src = ImportFileSystem.getResource(pathString)
|
||||||
|
|
||||||
src.origin shouldBe "library:/prog8lib/math.p8"
|
src.origin shouldBe "library:/prog8lib/math.p8"
|
||||||
src.text shouldBe normalizeLineEndings(srcFile.readText())
|
src.text shouldBe normalizeLineEndings(srcFile.readText())
|
||||||
@ -152,13 +153,13 @@ class TestSourceCode: AnnotationSpec() {
|
|||||||
val pathString = "/prog8lib/i_do_not_exist"
|
val pathString = "/prog8lib/i_do_not_exist"
|
||||||
assumeNotExists(resourcesDir, pathString.substring(1))
|
assumeNotExists(resourcesDir, pathString.substring(1))
|
||||||
|
|
||||||
shouldThrow<NoSuchFileException> { SourceCode.Resource(pathString) }
|
shouldThrow<NoSuchFileException> { ImportFileSystem.getResource(pathString) }
|
||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
fun testFromResourcesWithNonExistingFile_withoutLeadingSlash() {
|
fun testFromResourcesWithNonExistingFile_withoutLeadingSlash() {
|
||||||
val pathString = "prog8lib/i_do_not_exist"
|
val pathString = "prog8lib/i_do_not_exist"
|
||||||
assumeNotExists(resourcesDir, pathString)
|
assumeNotExists(resourcesDir, pathString)
|
||||||
|
|
||||||
shouldThrow<NoSuchFileException> { SourceCode.Resource(pathString) }
|
shouldThrow<NoSuchFileException> { ImportFileSystem.getResource(pathString) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package prog8.intermediate
|
|||||||
import prog8.code.core.InternalCompilerException
|
import prog8.code.core.InternalCompilerException
|
||||||
import prog8.code.core.Position
|
import prog8.code.core.Position
|
||||||
import prog8.code.core.toHex
|
import prog8.code.core.toHex
|
||||||
import prog8.code.source.SourceLineCache
|
import prog8.code.source.ImportFileSystem
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import javax.xml.stream.XMLOutputFactory
|
import javax.xml.stream.XMLOutputFactory
|
||||||
import javax.xml.stream.XMLStreamWriter
|
import javax.xml.stream.XMLStreamWriter
|
||||||
@ -149,10 +149,8 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
|
|||||||
xml.writeStartElement("P8SRC")
|
xml.writeStartElement("P8SRC")
|
||||||
val sourceTxt = StringBuilder("\n")
|
val sourceTxt = StringBuilder("\n")
|
||||||
code.sourceLinesPositions.forEach { pos ->
|
code.sourceLinesPositions.forEach { pos ->
|
||||||
val line = SourceLineCache.retrieveLine(pos)
|
val line = ImportFileSystem.retrieveSourceLine(pos)
|
||||||
if(line!=null) {
|
sourceTxt.append("$pos $line\n")
|
||||||
sourceTxt.append("$pos $line\n")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
xml.writeCData(sourceTxt.toString())
|
xml.writeCData(sourceTxt.toString())
|
||||||
xml.writeEndElement()
|
xml.writeEndElement()
|
||||||
|
Loading…
Reference in New Issue
Block a user