Repository: rokucommunity/brighterscript
Pull request #581 (2022-05-03 15:57:57)

Src path in v0
- Renames `pathAbsolute` to `srcPath` to align with the naming change in v1. 
- changes all internal calls to `getFileByPathAbsolute` to `getFile`
- adds `pathAbsolute` getter and setter to provide backwards compatibility support.

There's a small chance that this is a breaking change to plugins, but since we have the ability to lock bsc versions in vscode, I consider these acceptable risks. 
- if a plugin locks to an exact version of bsc, and vscode updates to a new version of bsc, the diagnostics produced by the latest bsc might cause the plugin to crash when looking for `pathAbsolute`.

NOTE: I tested this change while using bslint against the fubo codebase, and it still works, so I'm pretty comfortable with this change not breaking back-compat for most projects.


Patch:
diff --git a/benchmarks/targets/parse-xml.js b/benchmarks/targets/parse-xml.js
index bce170fc..1c6aed96 100644
--- a/benchmarks/targets/parse-xml.js
+++ b/benchmarks/targets/parse-xml.js
@@ -20,7 +20,7 @@ module.exports = async (suite, name, brighterscript, projectPath, options) => {
     suite.add(name, (deferred) => {
         const wait = [];
         for (const x of xmlFiles) {
-            const xmlFile = new XmlFile(x.pathAbsolute, x.pkgPath, builder.program);
+            const xmlFile = new XmlFile(x.srcPath ?? x.pathAbsolute, x.pkgPath, builder.program);
             //handle async and sync parsing
             const prom = xmlFile.parse(x.fileContents);
             if (prom) {
diff --git a/package-lock.json b/package-lock.json
index d2147701..c7f2cf47 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -85,7 +85,7 @@
                 "ts-node": "8.9.1",
                 "turndown": "^7.1.1",
                 "turndown-plugin-gfm": "^1.0.2",
-                "typescript": "^4.4.3",
+                "typescript": "^4.6.3",
                 "typescript-formatter": "^7.2.2",
                 "undent": "^0.1.0",
                 "vscode-jsonrpc": "^5.0.1"
@@ -7545,9 +7545,9 @@
             }
         },
         "node_modules/typescript": {
-            "version": "4.4.3",
-            "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz",
-            "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==",
+            "version": "4.6.3",
+            "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz",
+            "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==",
             "dev": true,
             "bin": {
                 "tsc": "bin/tsc",
@@ -13672,9 +13672,9 @@
             }
         },
         "typescript": {
-            "version": "4.4.3",
-            "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz",
-            "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==",
+            "version": "4.6.3",
+            "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz",
+            "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==",
             "dev": true
         },
         "typescript-formatter": {
diff --git a/package.json b/package.json
index da5487e7..d7a91666 100644
--- a/package.json
+++ b/package.json
@@ -113,7 +113,7 @@
         "ts-node": "8.9.1",
         "turndown": "^7.1.1",
         "turndown-plugin-gfm": "^1.0.2",
-        "typescript": "^4.4.3",
+        "typescript": "^4.6.3",
         "typescript-formatter": "^7.2.2",
         "undent": "^0.1.0",
         "vscode-jsonrpc": "^5.0.1"
diff --git a/scripts/compile-doc-examples.ts b/scripts/compile-doc-examples.ts
index 372137b6..a68fa004 100644
--- a/scripts/compile-doc-examples.ts
+++ b/scripts/compile-doc-examples.ts
@@ -186,7 +186,7 @@ class DocCompiler {
         });
         const file = program.setFile({ src: `${__dirname}/rootDir/source/main.bs`, dest: 'source/main.bs' }, code);
         program.validate();
-        const tranpileResult = program.getTranspiledFileContents(file.pathAbsolute).code;
+        const tranpileResult = program.getTranspiledFileContents(file.srcPath).code;
         return tranpileResult.trim();
     }
 }
diff --git a/src/DiagnosticCollection.spec.ts b/src/DiagnosticCollection.spec.ts
index 2404fe2a..a2e08fb9 100644
--- a/src/DiagnosticCollection.spec.ts
+++ b/src/DiagnosticCollection.spec.ts
@@ -84,22 +84,22 @@ describe('DiagnosticCollection', () => {
         });
     });
 
-    function removeDiagnostic(filePath: string, message: string) {
+    function removeDiagnostic(srcPath: string, message: string) {
         for (let i = 0; i < diagnostics.length; i++) {
             const diagnostic = diagnostics[i];
-            if (diagnostic.file.pathAbsolute === filePath && diagnostic.message === message) {
+            if (diagnostic.file.srcPath === srcPath && diagnostic.message === message) {
                 diagnostics.splice(i, 1);
                 return;
             }
         }
-        throw new Error(`Cannot find diagnostic ${filePath}:${message}`);
+        throw new Error(`Cannot find diagnostic ${srcPath}:${message}`);
     }
 
-    function addDiagnostics(filePath: string, messages: string[]) {
+    function addDiagnostics(srcPath: string, messages: string[]) {
         for (const message of messages) {
             diagnostics.push({
                 file: {
-                    pathAbsolute: filePath
+                    srcPath: srcPath
                 } as BscFile,
                 range: util.createRange(0, 0, 0, 0),
                 //the code doesn't matter as long as the messages are different, so just enforce unique messages for this test files
diff --git a/src/DiagnosticCollection.ts b/src/DiagnosticCollection.ts
index 59fbe101..583c9b6d 100644
--- a/src/DiagnosticCollection.ts
+++ b/src/DiagnosticCollection.ts
@@ -34,15 +34,15 @@ export class DiagnosticCollection {
         const keys = {};
         //build the full current set of diagnostics by file
         for (let diagnostic of diagnostics) {
-            const filePath = diagnostic.file.pathAbsolute;
+            const srcPath = diagnostic.file.srcPath ?? diagnostic.file.srcPath;
             //ensure the file entry exists
-            if (!result[filePath]) {
-                result[filePath] = [];
+            if (!result[srcPath]) {
+                result[srcPath] = [];
             }
-            const diagnosticMap = result[filePath];
+            const diagnosticMap = result[srcPath];
 
             diagnostic.key =
-                diagnostic.file.pathAbsolute.toLowerCase() + '-' +
+                srcPath.toLowerCase() + '-' +
                 diagnostic.code + '-' +
                 diagnostic.range.start.line + '-' +
                 diagnostic.range.start.character + '-' +
diff --git a/src/DiagnosticFilterer.spec.ts b/src/DiagnosticFilterer.spec.ts
index 49e60f88..1570f329 100644
--- a/src/DiagnosticFilterer.spec.ts
+++ b/src/DiagnosticFilterer.spec.ts
@@ -170,10 +170,10 @@ describe('DiagnosticFilterer', () => {
 
 });
 
-function getDiagnostic(code: number | string, pathAbsolute: string) {
+function getDiagnostic(code: number | string, srcPath: string) {
     return {
         file: {
-            pathAbsolute: s`${pathAbsolute}`
+            srcPath: s`${srcPath}`
         },
         code: code
     } as BsDiagnostic;
diff --git a/src/DiagnosticFilterer.ts b/src/DiagnosticFilterer.ts
index b14a794c..874a6d93 100644
--- a/src/DiagnosticFilterer.ts
+++ b/src/DiagnosticFilterer.ts
@@ -58,11 +58,12 @@ export class DiagnosticFilterer {
         this.byFile = {};
 
         for (let diagnostic of diagnostics) {
+            const srcPath = diagnostic?.file?.srcPath ?? diagnostic?.file?.srcPath;
             //skip diagnostics that have issues
-            if (!diagnostic?.file?.pathAbsolute) {
+            if (!srcPath) {
                 continue;
             }
-            const lowerSrcPath = diagnostic.file.pathAbsolute.toLowerCase();
+            const lowerSrcPath = srcPath.toLowerCase();
             //make a new array for this file if one does not yet exist
             if (!this.byFile[lowerSrcPath]) {
                 this.byFile[lowerSrcPath] = [];
diff --git a/src/LanguageServer.spec.ts b/src/LanguageServer.spec.ts
index 96e3dbd9..da07382b 100644
--- a/src/LanguageServer.spec.ts
+++ b/src/LanguageServer.spec.ts
@@ -82,11 +82,11 @@ describe('LanguageServer', () => {
 
         //hijack the file resolver so we can inject in-memory files for our tests
         let originalResolver = svr.documentFileResolver;
-        svr.documentFileResolver = (pathAbsolute: string) => {
-            if (vfs[pathAbsolute]) {
-                return vfs[pathAbsolute];
+        svr.documentFileResolver = (srcPath: string) => {
+            if (vfs[srcPath]) {
+                return vfs[srcPath];
             } else {
-                return originalResolver.call(svr, pathAbsolute);
+                return originalResolver.call(svr, srcPath);
             }
         };
 
@@ -98,7 +98,7 @@ describe('LanguageServer', () => {
     afterEach(async () => {
         try {
             await Promise.all(
-                physicalFilePaths.map(pathAbsolute => fsExtra.unlinkSync(pathAbsolute))
+                physicalFilePaths.map(srcPath => fsExtra.unlinkSync(srcPath))
             );
         } catch (e) {
 
@@ -121,16 +121,16 @@ describe('LanguageServer', () => {
         const filePath = s`components/${name}.${extension}`;
         const file = program.setFile(filePath, contents);
         if (file) {
-            const document = TextDocument.create(util.pathToUri(file.pathAbsolute), 'brightscript', 1, contents);
+            const document = TextDocument.create(util.pathToUri(file.srcPath), 'brightscript', 1, contents);
             svr.documents._documents[document.uri] = document;
             return document;
         }
     }
 
-    function writeToFs(pathAbsolute: string, contents: string) {
-        physicalFilePaths.push(pathAbsolute);
-        fsExtra.ensureDirSync(path.dirname(pathAbsolute));
-        fsExtra.writeFileSync(pathAbsolute, contents);
+    function writeToFs(srcPath: string, contents: string) {
+        physicalFilePaths.push(srcPath);
+        fsExtra.ensureDirSync(path.dirname(srcPath));
+        fsExtra.writeFileSync(srcPath, contents);
     }
 
     describe('createStandaloneFileWorkspace', () => {
@@ -191,7 +191,7 @@ describe('LanguageServer', () => {
                     getDiagnostics: () => {
                         return [{
                             file: {
-                                pathAbsolute: s`${rootDir}/source/main.brs`
+                                srcPath: s`${rootDir}/source/main.brs`
                             },
                             code: 1000,
                             range: Range.create(1, 2, 3, 4)
@@ -204,7 +204,7 @@ describe('LanguageServer', () => {
                     getDiagnostics: () => {
                         return [{
                             file: {
-                                pathAbsolute: s`${rootDir}/source/main.brs`
+                                srcPath: s`${rootDir}/source/main.brs`
                             },
                             code: 1000,
                             range: Range.create(1, 2, 3, 4)
@@ -292,7 +292,7 @@ describe('LanguageServer', () => {
 
             await server.handleFileChanges(workspace, [{
                 type: FileChangeType.Created,
-                pathAbsolute: mainPath
+                srcPath: mainPath
             }]);
 
             expect(setFileStub.getCalls()[0]?.args[0]).to.eql({
@@ -305,7 +305,7 @@ describe('LanguageServer', () => {
             expect(setFileStub.callCount).to.equal(1);
             await server.handleFileChanges(workspace, [{
                 type: FileChangeType.Created,
-                pathAbsolute: libPath
+                srcPath: libPath
             }]);
             //the function should have ignored the lib file, so no additional files were added
             expect(setFileStub.callCount).to.equal(1);
@@ -345,10 +345,10 @@ describe('LanguageServer', () => {
 
             expect(stub.getCalls()[0].args[1]).to.eql([{
                 type: FileChangeType.Created,
-                pathAbsolute: s`${rootDir}/source/main.brs`
+                srcPath: s`${rootDir}/source/main.brs`
             }, {
                 type: FileChangeType.Created,
-                pathAbsolute: s`${rootDir}/source/lib.brs`
+                srcPath: s`${rootDir}/source/lib.brs`
             }]);
         });
 
@@ -383,10 +383,10 @@ describe('LanguageServer', () => {
 
             expect(stub.getCalls()[0].args[1]).to.eql([{
                 type: FileChangeType.Created,
-                pathAbsolute: s`${rootDir}/source/main.brs`
+                srcPath: s`${rootDir}/source/main.brs`
             }, {
                 type: FileChangeType.Created,
-                pathAbsolute: s`${rootDir}/source/lib.brs`
+                srcPath: s`${rootDir}/source/lib.brs`
             }]);
         });
     });
@@ -877,6 +877,14 @@ describe('LanguageServer', () => {
             }
         });
     });
+
+    describe('CustomCommands', () => {
+        describe('TranspileFile', () => {
+            it('returns pathAbsolute to support backwards compatibility', () => {
+
+            });
+        });
+    });
 });
 
 export function getFileProtocolPath(fullPath: string) {
diff --git a/src/LanguageServer.ts b/src/LanguageServer.ts
index 71ee86ca..8e58e935 100644
--- a/src/LanguageServer.ts
+++ b/src/LanguageServer.ts
@@ -447,10 +447,10 @@ export class LanguageServer {
         });
     }
 
-    private async createStandaloneFileWorkspace(filePathAbsolute: string) {
+    private async createStandaloneFileWorkspace(srcPath: string) {
         //skip this workspace if we already have it
-        if (this.standaloneFileWorkspaces[filePathAbsolute]) {
-            return this.standaloneFileWorkspaces[filePathAbsolute];
+        if (this.standaloneFileWorkspaces[srcPath]) {
+            return this.standaloneFileWorkspaces[srcPath];
         }
 
         let builder = new ProgramBuilder();
@@ -462,10 +462,10 @@ export class LanguageServer {
         builder.addFileResolver(this.documentFileResolver.bind(this));
 
         //get the path to the directory where this file resides
-        let cwd = path.dirname(filePathAbsolute);
+        let cwd = path.dirname(srcPath);
 
         //get the closest config file and use most of the settings from that
-        let configFilePath = await util.findClosestConfigFile(filePathAbsolute);
+        let configFilePath = await util.findClosestConfigFile(srcPath);
         let project: BsConfig = {};
         if (configFilePath) {
             project = util.normalizeAndResolveConfig({ project: configFilePath });
@@ -473,8 +473,8 @@ export class LanguageServer {
         //override the rootDir and files array
         project.rootDir = cwd;
         project.files = [{
-            src: filePathAbsolute,
-            dest: path.basename(filePathAbsolute)
+            src: srcPath,
+            dest: path.basename(srcPath)
         }];
 
         let firstRunPromise = builder.run({
@@ -496,14 +496,14 @@ export class LanguageServer {
         let newWorkspace: Workspace = {
             builder: builder,
             firstRunPromise: firstRunPromise,
-            workspacePath: filePathAbsolute,
+            workspacePath: srcPath,
             isFirstRunComplete: false,
             isFirstRunSuccessful: false,
             configFilePath: configFilePath,
             isStandaloneFileWorkspace: true
         };
 
-        this.standaloneFileWorkspaces[filePathAbsolute] = newWorkspace;
+        this.standaloneFileWorkspaces[srcPath] = newWorkspace;
 
         await firstRunPromise.then(() => {
             newWorkspace.isFirstRunComplete = true;
@@ -719,14 +719,14 @@ export class LanguageServer {
         let changes = params.changes.map(x => {
             return {
                 type: x.type,
-                pathAbsolute: s`${URI.parse(x.uri).fsPath}`
+                srcPath: s`${URI.parse(x.uri).fsPath}`
             };
         });
 
-        let keys = changes.map(x => x.pathAbsolute);
+        let keys = changes.map(x => x.srcPath);
 
         //filter the list of changes to only the ones that made it through the debounce unscathed
-        changes = changes.filter(x => keys.includes(x.pathAbsolute));
+        changes = changes.filter(x => keys.includes(x.srcPath));
 
         //if we have changes to work with
         if (changes.length > 0) {
@@ -735,7 +735,7 @@ export class LanguageServer {
             {
                 let workspacesToReload = [] as Workspace[];
                 //get the file paths as a string array
-                let filePaths = changes.map((x) => x.pathAbsolute);
+                let filePaths = changes.map((x) => x.srcPath);
 
                 for (let workspace of workspaces) {
                     if (workspace.configFilePath && filePaths.includes(workspace.configFilePath)) {
@@ -757,7 +757,7 @@ export class LanguageServer {
                 //get only creation items
                 .filter(change => change.type === FileChangeType.Created)
                 //keep only the directories
-                .filter(change => util.isDirectorySync(change.pathAbsolute));
+                .filter(change => util.isDirectorySync(change.srcPath));
 
             //remove the created directories from the changes array (we will add back each of their files next)
             changes = changes.filter(x => !directoryChanges.includes(x));
@@ -765,7 +765,7 @@ export class LanguageServer {
             //look up every file in each of the newly added directories
             const newFileChanges = directoryChanges
                 //take just the path
-                .map(x => x.pathAbsolute)
+                .map(x => x.srcPath)
                 //exclude the roku deploy staging folder
                 .filter(dirPath => !dirPath.includes('.roku-deploy-staging'))
                 //get the files for each folder recursively
@@ -778,7 +778,7 @@ export class LanguageServer {
                     return files.map(x => {
                         return {
                             type: FileChangeType.Created,
-                            pathAbsolute: s`${x}`
+                            srcPath: s`${x}`
                         };
                     });
                 });
@@ -799,12 +799,12 @@ export class LanguageServer {
      * any file changes you receive with no unexpected side-effects
      * @param changes
      */
-    public async handleFileChanges(workspace: Workspace, changes: { type: FileChangeType; pathAbsolute: string }[]) {
+    public async handleFileChanges(workspace: Workspace, changes: { type: FileChangeType; srcPath: string }[]) {
         //this loop assumes paths are both file paths and folder paths, which eliminates the need to detect.
         //All functions below can handle being given a file path AND a folder path, and will only operate on the one they are looking for
         let consumeCount = 0;
         await Promise.all(changes.map(async (change) => {
-            await this.keyedThrottler.run(change.pathAbsolute, async () => {
+            await this.keyedThrottler.run(change.srcPath, async () => {
                 consumeCount += await this.handleFileChange(workspace, change) ? 1 : 0;
             });
         }));
@@ -819,7 +819,7 @@ export class LanguageServer {
      * any file changes you receive with no unexpected side-effects
      * @param changes
      */
-    private async handleFileChange(workspace: Workspace, change: { type: FileChangeType; pathAbsolute: string }) {
+    private async handleFileChange(workspace: Workspace, change: { type: FileChangeType; srcPath: string }) {
         const program = workspace.builder.program;
         const options = workspace.builder.options;
         const rootDir = workspace.builder.rootDir;
@@ -827,11 +827,11 @@ export class LanguageServer {
         //deleted
         if (change.type === FileChangeType.Deleted) {
             //try to act on this path as a directory
-            workspace.builder.removeFilesInFolder(change.pathAbsolute);
+            workspace.builder.removeFilesInFolder(change.srcPath);
 
             //if this is a file loaded in the program, remove it
-            if (program.hasFile(change.pathAbsolute)) {
-                program.removeFile(change.pathAbsolute);
+            if (program.hasFile(change.srcPath)) {
+                program.removeFile(change.srcPath);
                 return true;
             } else {
                 return false;
@@ -842,16 +842,16 @@ export class LanguageServer {
             // thanks to `onDidChangeWatchedFiles`, we can safely assume that all "Created" changes are file paths, (not directories)
 
             //get the dest path for this file.
-            let destPath = rokuDeploy.getDestPath(change.pathAbsolute, options.files, rootDir);
+            let destPath = rokuDeploy.getDestPath(change.srcPath, options.files, rootDir);
 
             //if we got a dest path, then the program wants this file
             if (destPath) {
                 program.setFile(
                     {
-                        src: change.pathAbsolute,
-                        dest: rokuDeploy.getDestPath(change.pathAbsolute, options.files, rootDir)
+                        src: change.srcPath,
+                        dest: rokuDeploy.getDestPath(change.srcPath, options.files, rootDir)
                     },
-                    await workspace.builder.getFileContents(change.pathAbsolute)
+                    await workspace.builder.getFileContents(change.srcPath)
                 );
                 return true;
             } else {
@@ -860,19 +860,19 @@ export class LanguageServer {
             }
 
             //changed
-        } else if (program.hasFile(change.pathAbsolute)) {
+        } else if (program.hasFile(change.srcPath)) {
             //sometimes "changed" events are emitted on files that were actually deleted,
             //so determine file existance and act accordingly
-            if (await util.pathExists(change.pathAbsolute)) {
+            if (await util.pathExists(change.srcPath)) {
                 program.setFile(
                     {
-                        src: change.pathAbsolute,
-                        dest: rokuDeploy.getDestPath(change.pathAbsolute, options.files, rootDir)
+                        src: change.srcPath,
+                        dest: rokuDeploy.getDestPath(change.srcPath, options.files, rootDir)
                     },
-                    await workspace.builder.getFileContents(change.pathAbsolute)
+                    await workspace.builder.getFileContents(change.srcPath)
                 );
             } else {
-                program.removeFile(change.pathAbsolute);
+                program.removeFile(change.srcPath);
             }
             return true;
         }
@@ -883,11 +883,11 @@ export class LanguageServer {
         //ensure programs are initialized
         await this.waitAllProgramFirstRuns();
 
-        let pathAbsolute = util.uriToPath(params.textDocument.uri);
+        const srcPath = util.uriToPath(params.textDocument.uri);
         let workspaces = this.getWorkspaces();
         let hovers = await Promise.all(
             Array.prototype.concat.call([],
-                workspaces.map(async (x) => x.builder.program.getHover(pathAbsolute, params.position))
+                workspaces.map(async (x) => x.builder.program.getHover(srcPath, params.position))
             )
         ) as Hover[];
 
@@ -991,9 +991,9 @@ export class LanguageServer {
 
         await this.keyedThrottler.onIdleOnce(util.uriToPath(params.textDocument.uri), true);
 
-        const pathAbsolute = util.uriToPath(params.textDocument.uri);
+        const srcPath = util.uriToPath(params.textDocument.uri);
         for (const workspace of this.getWorkspaces()) {
-            const file = workspace.builder.program.getFileByPathAbsolute(pathAbsolute);
+            const file = workspace.builder.program.getFile(srcPath);
             if (isBrsFile(file)) {
                 return file.getDocumentSymbols();
             }
@@ -1004,11 +1004,11 @@ export class LanguageServer {
     private async onDefinition(params: TextDocumentPositionParams) {
         await this.waitAllProgramFirstRuns();
 
-        const pathAbsolute = util.uriToPath(params.textDocument.uri);
+        const srcPath = util.uriToPath(params.textDocument.uri);
 
         const results = util.flatMap(
             await Promise.all(this.getWorkspaces().map(workspace => {
-                return workspace.builder.program.getDefinition(pathAbsolute, params.position);
+                return workspace.builder.program.getDefinition(srcPath, params.position);
             })),
             c => c
         );
@@ -1054,11 +1054,11 @@ export class LanguageServer {
         await this.waitAllProgramFirstRuns();
 
         const position = params.position;
-        const pathAbsolute = util.uriToPath(params.textDocument.uri);
+        const srcPath = util.uriToPath(params.textDocument.uri);
 
         const results = util.flatMap(
             await Promise.all(this.getWorkspaces().map(workspace => {
-                return workspace.builder.program.getReferences(pathAbsolute, position);
+                return workspace.builder.program.getReferences(srcPath, position);
             })),
             c => c
         );
@@ -1102,18 +1102,20 @@ export class LanguageServer {
     public async onExecuteCommand(params: ExecuteCommandParams) {
         await this.waitAllProgramFirstRuns();
         if (params.command === CustomCommands.TranspileFile) {
-            return this.transpileFile(params.arguments[0]);
+            const result = await this.transpileFile(params.arguments[0]);
+            //back-compat: include `pathAbsolute` property so older vscode versions still work
+            (result as any).pathAbsolute = result.srcPath;
         }
     }
 
-    private async transpileFile(pathAbsolute: string) {
+    private async transpileFile(srcPath: string) {
         //wait all program first runs
         await this.waitAllProgramFirstRuns();
         let workspaces = this.getWorkspaces();
         //find the first workspace that has this file
         for (let workspace of workspaces) {
-            if (workspace.builder.program.hasFile(pathAbsolute)) {
-                return workspace.builder.program.getTranspiledFileContents(pathAbsolute);
+            if (workspace.builder.program.hasFile(srcPath)) {
+                return workspace.builder.program.getTranspiledFileContents(srcPath);
             }
         }
     }
diff --git a/src/Program.spec.ts b/src/Program.spec.ts
index 83180078..ae359e90 100644
--- a/src/Program.spec.ts
+++ b/src/Program.spec.ts
@@ -105,7 +105,7 @@ describe('Program', () => {
                 end sub
             `);
             (file.parser.ast.statements[0] as FunctionStatement).func.body.statements[0] = new EmptyStatement();
-            await program.transpile([{ src: file.pathAbsolute, dest: file.pkgPath }], tmpPath);
+            await program.transpile([{ src: file.srcPath, dest: file.pkgPath }], tmpPath);
         });
 
         it('works with different cwd', () => {
@@ -578,9 +578,9 @@ describe('Program', () => {
         });
 
         it('adds xml file to files map', () => {
-            let xmlPath = `${rootDir}/components/component1.xml`;
-            program.setFile({ src: xmlPath, dest: 'components/component1.xml' }, '');
-            expect(program.getFileByPathAbsolute(xmlPath)).to.exist;
+            let srcPath = `${rootDir}/components/component1.xml`;
+            program.setFile({ src: srcPath, dest: 'components/component1.xml' }, '');
+            expect(program.getFile(srcPath)).to.exist;
         });
 
         it('detects missing script reference', () => {
@@ -1444,8 +1444,8 @@ describe('Program', () => {
             let ctx = program.getScopeByName(xmlFile.pkgPath);
             //the component scope should have the xml file AND the lib file
             expect(ctx.getOwnFiles().length).to.equal(2);
-            expect(ctx.getFile(xmlFile.pathAbsolute)).to.exist;
-            expect(ctx.getFile(libFile.pathAbsolute)).to.exist;
+            expect(ctx.getFile(xmlFile.srcPath)).to.exist;
+            expect(ctx.getFile(libFile.srcPath)).to.exist;
 
             //reload the xml file again, removing the script import.
             xmlFile = program.setFile({ src: `${rootDir}/components/component.xml`, dest: 'components/component.xml' }, trim`
@@ -1482,14 +1482,14 @@ describe('Program', () => {
 
     describe('getDiagnostics', () => {
         it('includes diagnostics from files not included in any scope', () => {
-            let pathAbsolute = s`${rootDir}/components/a/b/c/main.brs`;
-            program.setFile({ src: pathAbsolute, dest: 'components/a/b/c/main.brs' }, `
+            let srcPath = s`${rootDir}/components/a/b/c/main.brs`;
+            program.setFile({ src: srcPath, dest: 'components/a/b/c/main.brs' }, `
                 sub A()
                     "this string is not terminated
                 end sub
             `);
             //the file should be included in the program
-            expect(program.getFileByPathAbsolute(pathAbsolute)).to.exist;
+            expect(program.getFile(srcPath)).to.exist;
             let diagnostics = program.getDiagnostics();
             expectHasDiagnostics(diagnostics);
             let parseError = diagnostics.filter(x => x.message === 'Unterminated string at end of line')[0];
@@ -1673,7 +1673,7 @@ describe('Program', () => {
                 afterFileTranspile: sinon.spy()
             });
             expect(
-                program.getTranspiledFileContents(file.pathAbsolute).code
+                program.getTranspiledFileContents(file.srcPath).code
             ).to.eql(trim`
                 sub main()
                     print "hello there"
@@ -2069,7 +2069,7 @@ describe('Program', () => {
                     someFunc()@.
                 end sub
             `);
-            program.getCompletions(file.pathAbsolute, util.createPosition(2, 32));
+            program.getCompletions(file.srcPath, util.createPosition(2, 32));
         });
 
         it('gets signature help for constructor with no args', () => {
diff --git a/src/Program.ts b/src/Program.ts
index d0d9788c..24e60d8b 100644
--- a/src/Program.ts
+++ b/src/Program.ts
@@ -31,7 +31,11 @@ const bslibNonAliasedRokuModulesPkgPath = s`source/roku_modules/rokucommunity_bs
 const bslibAliasedRokuModulesPkgPath = s`source/roku_modules/bslib/bslib.brs`;
 
 export interface SourceObj {
+    /**
+     * @deprecated use `srcPath` instead
+     */
     pathAbsolute: string;
+    srcPath: string;
     source: string;
     definitions?: string;
 }
@@ -336,7 +340,7 @@ export class Program {
      * Update internal maps with this file reference
      */
     private assignFile<T extends BscFile = BscFile>(file: T) {
-        this.files[file.pathAbsolute.toLowerCase()] = file;
+        this.files[file.srcPath.toLowerCase()] = file;
         this.pkgMap[file.pkgPath.toLowerCase()] = file;
         return file;
     }
@@ -345,7 +349,7 @@ export class Program {
      * Remove this file from internal maps
      */
     private unassignFile<T extends BscFile = BscFile>(file: T) {
-        delete this.files[file.pathAbsolute.toLowerCase()];
+        delete this.files[file.srcPath.toLowerCase()];
         delete this.pkgMap[file.pkgPath.toLowerCase()];
         return file;
     }
@@ -418,7 +422,9 @@ export class Program {
                 }
 
                 let sourceObj: SourceObj = {
+                    //TODO remove `pathAbsolute` in v1
                     pathAbsolute: srcPath,
+                    srcPath: srcPath,
                     source: fileContents
                 };
                 this.plugins.emit('beforeFileParse', sourceObj);
@@ -446,7 +452,9 @@ export class Program {
                 );
 
                 let sourceObj: SourceObj = {
+                    //TODO remove `pathAbsolute` in v1
                     pathAbsolute: srcPath,
+                    srcPath: srcPath,
                     source: fileContents
                 };
                 this.plugins.emit('beforeFileParse', sourceObj);
@@ -469,8 +477,8 @@ export class Program {
 
             } else {
                 //TODO do we actually need to implement this? Figure out how to handle img paths
-                // let genericFile = this.files[pathAbsolute] = <any>{
-                //     pathAbsolute: pathAbsolute,
+                // let genericFile = this.files[srcPath] = <any>{
+                //     srcPath: srcPath,
                 //     pkgPath: pkgPath,
                 //     wasProcessed: true
                 // } as File;
@@ -497,13 +505,13 @@ export class Program {
      * Find the file by its absolute path. This is case INSENSITIVE, since
      * Roku is a case insensitive file system. It is an error to have multiple files
      * with the same path with only case being different.
-     * @param pathAbsolute
+     * @param srcPath
      * @deprecated use `getFile` instead, which auto-detects the path type
      */
-    public getFileByPathAbsolute<T extends BrsFile | XmlFile>(pathAbsolute: string) {
-        pathAbsolute = s`${pathAbsolute}`;
+    public getFileByPathAbsolute<T extends BrsFile | XmlFile>(srcPath: string) {
+        srcPath = s`${srcPath}`;
         for (let filePath in this.files) {
-            if (filePath.toLowerCase() === pathAbsolute.toLowerCase()) {
+            if (filePath.toLowerCase() === srcPath.toLowerCase()) {
                 return this.files[filePath] as T;
             }
         }
@@ -669,7 +677,7 @@ export class Program {
                         relatedInformation: xmlFiles.filter(x => x !== xmlFile).map(x => {
                             return {
                                 location: Location.create(
-                                    URI.file(xmlFile.pathAbsolute).toString(),
+                                    URI.file(xmlFile.srcPath ?? xmlFile.srcPath).toString(),
                                     x.componentName.range
                                 ),
                                 message: 'Also defined here'
@@ -879,8 +887,8 @@ export class Program {
      * Given a position in a file, if the position is sitting on some type of identifier,
      * go to the definition of that identifier (where this thing was first defined)
      */
-    public getDefinition(pathAbsolute: string, position: Position) {
-        let file = this.getFile(pathAbsolute);
+    public getDefinition(srcPath: string, position: Position) {
+        let file = this.getFile(srcPath);
         if (!file) {
             return [];
         }
@@ -897,9 +905,9 @@ export class Program {
         }
     }
 
-    public getHover(pathAbsolute: string, position: Position) {
+    public getHover(srcPath: string, position: Position) {
         //find the file
-        let file = this.getFile(pathAbsolute);
+        let file = this.getFile(srcPath);
         if (!file) {
             return null;
         }
@@ -911,9 +919,9 @@ export class Program {
     /**
      * Compute code actions for the given file and range
      */
-    public getCodeActions(pathAbsolute: string, range: Range) {
+    public getCodeActions(srcPath: string, range: Range) {
         const codeActions = [] as CodeAction[];
-        const file = this.getFile(pathAbsolute);
+        const file = this.getFile(srcPath);
         if (file) {
             const diagnostics = this
                 //get all current diagnostics (filtered by diagnostic filters)
@@ -1180,9 +1188,9 @@ export class Program {
 
     }
 
-    public getReferences(pathAbsolute: string, position: Position) {
+    public getReferences(srcPath: string, position: Position) {
         //find the file
-        let file = this.getFile(pathAbsolute);
+        let file = this.getFile(srcPath);
         if (!file) {
             return null;
         }
@@ -1223,7 +1231,7 @@ export class Program {
 
                     result.push({
                         label: relativePath,
-                        detail: file.pathAbsolute,
+                        detail: file.srcPath,
                         kind: CompletionItemKind.File,
                         textEdit: {
                             newText: relativePath,
@@ -1234,7 +1242,7 @@ export class Program {
                     //add the absolute path
                     result.push({
                         label: filePkgPath,
-                        detail: file.pathAbsolute,
+                        detail: file.srcPath,
                         kind: CompletionItemKind.File,
                         textEdit: {
                             newText: filePkgPath,
@@ -1303,7 +1311,7 @@ export class Program {
         editor.undoAll();
 
         return {
-            pathAbsolute: file.pathAbsolute,
+            srcPath: file.srcPath,
             pkgPath: file.pkgPath,
             code: event.code,
             map: event.map,
@@ -1319,7 +1327,7 @@ export class Program {
         }, {});
 
         const getOutputPath = (file: BscFile) => {
-            let filePathObj = mappedFileEntries[s`${file.pathAbsolute}`];
+            let filePathObj = mappedFileEntries[s`${file.srcPath}`];
             if (!filePathObj) {
                 //this file has been added in-memory, from a plugin, for example
                 filePathObj = {
@@ -1352,7 +1360,7 @@ export class Program {
             await fsExtra.ensureDir(path.dirname(outputPath));
 
             if (await fsExtra.pathExists(outputPath)) {
-                throw new Error(`Error while transpiling "${file.pathAbsolute}". A file already exists at "${outputPath}" and will not be overwritten.`);
+                throw new Error(`Error while transpiling "${file.srcPath}". A file already exists at "${outputPath}" and will not be overwritten.`);
             }
             const writeMapPromise = fileTranspileResult.map ? fsExtra.writeFile(`${outputPath}.map`, fileTranspileResult.map.toString()) : null;
             await Promise.all([
@@ -1483,7 +1491,7 @@ export class Program {
 }
 
 export interface FileTranspileResult {
-    pathAbsolute: string;
+    srcPath: string;
     pkgPath: string;
     code: string;
     map: SourceMapGenerator;
diff --git a/src/ProgramBuilder.spec.ts b/src/ProgramBuilder.spec.ts
index cde88c74..842b3240 100644
--- a/src/ProgramBuilder.spec.ts
+++ b/src/ProgramBuilder.spec.ts
@@ -148,7 +148,7 @@ describe('ProgramBuilder', () => {
                 }]
             });
             expectZeroDiagnostics(builder);
-            expect(builder.program.getFileByPathAbsolute(s``));
+            expect(builder.program.getFile(s``));
         });
     });
 
@@ -240,7 +240,7 @@ describe('ProgramBuilder', () => {
             f1.fileContents = `l1\nl2\nl3`;
             sinon.stub(builder, 'getDiagnostics').returns(diagnostics);
 
-            sinon.stub(builder.program, 'getFileByPathAbsolute').returns(f1);
+            sinon.stub(builder.program, 'getFile').returns(f1);
 
             let printStub = sinon.stub(diagnosticUtils, 'printDiagnostic');
 
@@ -258,7 +258,7 @@ describe('ProgramBuilder', () => {
         f1.fileContents = null;
         sinon.stub(builder, 'getDiagnostics').returns(diagnostics);
 
-        sinon.stub(builder.program, 'getFileByPathAbsolute').returns(f1);
+        sinon.stub(builder.program, 'getFile').returns(f1);
 
         let printStub = sinon.stub(diagnosticUtils, 'printDiagnostic');
 
@@ -273,7 +273,7 @@ describe('ProgramBuilder', () => {
         let diagnostics = createBsDiagnostic('p1', ['m1']);
         sinon.stub(builder, 'getDiagnostics').returns(diagnostics);
 
-        sinon.stub(builder.program, 'getFileByPathAbsolute').returns(null);
+        sinon.stub(builder.program, 'getFile').returns(null);
 
         let printStub = sinon.stub(diagnosticUtils, 'printDiagnostic');
 
diff --git a/src/ProgramBuilder.ts b/src/ProgramBuilder.ts
index 4fa2f953..c074d2b6 100644
--- a/src/ProgramBuilder.ts
+++ b/src/ProgramBuilder.ts
@@ -47,16 +47,16 @@ export class ProgramBuilder {
      * This walks backwards through the file resolvers until we get a value.
      * This allow the language server to provide file contents directly from memory.
      */
-    public async getFileContents(pathAbsolute: string) {
-        pathAbsolute = s`${pathAbsolute}`;
+    public async getFileContents(srcPath: string) {
+        srcPath = s`${srcPath}`;
         let reversedResolvers = [...this.fileResolvers].reverse();
         for (let fileResolver of reversedResolvers) {
-            let result = await fileResolver(pathAbsolute);
+            let result = await fileResolver(srcPath);
             if (typeof result === 'string') {
                 return result;
             }
         }
-        throw new Error(`Could not load file "${pathAbsolute}"`);
+        throw new Error(`Could not load file "${srcPath}"`);
     }
 
     /**
@@ -64,12 +64,13 @@ export class ProgramBuilder {
      */
     private staticDiagnostics = [] as BsDiagnostic[];
 
-    public addDiagnostic(filePathAbsolute: string, diagnostic: Partial<BsDiagnostic>) {
-        let file: BscFile = this.program.getFileByPathAbsolute(filePathAbsolute);
+    public addDiagnostic(srcPath: string, diagnostic: Partial<BsDiagnostic>) {
+        let file: BscFile = this.program.getFile(srcPath);
         if (!file) {
             file = {
-                pkgPath: this.program.getPkgPath(filePathAbsolute),
-                pathAbsolute: filePathAbsolute,
+                pkgPath: this.program.getPkgPath(srcPath),
+                pathAbsolute: srcPath, //keep this for backwards-compatibility. TODO remove in v1
+                srcPath: srcPath,
                 getDiagnostics: () => {
                     return [<any>diagnostic];
                 }
@@ -274,19 +275,19 @@ export class ProgramBuilder {
         //group the diagnostics by file
         let diagnosticsByFile = {} as Record<string, BsDiagnostic[]>;
         for (let diagnostic of diagnostics) {
-            if (!diagnosticsByFile[diagnostic.file.pathAbsolute]) {
-                diagnosticsByFile[diagnostic.file.pathAbsolute] = [];
+            if (!diagnosticsByFile[diagnostic.file.srcPath]) {
+                diagnosticsByFile[diagnostic.file.srcPath] = [];
             }
-            diagnosticsByFile[diagnostic.file.pathAbsolute].push(diagnostic);
+            diagnosticsByFile[diagnostic.file.srcPath].push(diagnostic);
         }
 
         //get printing options
         const options = diagnosticUtils.getPrintDiagnosticOptions(this.options);
         const { cwd, emitFullPaths } = options;
 
-        let pathsAbsolute = Object.keys(diagnosticsByFile).sort();
-        for (let pathAbsolute of pathsAbsolute) {
-            let diagnosticsForFile = diagnosticsByFile[pathAbsolute];
+        let srcPaths = Object.keys(diagnosticsByFile).sort();
+        for (let srcPath of srcPaths) {
+            let diagnosticsForFile = diagnosticsByFile[srcPath];
             //sort the diagnostics in line and column order
             let sortedDiagnostics = diagnosticsForFile.sort((a, b) => {
                 return (
@@ -295,12 +296,12 @@ export class ProgramBuilder {
                 );
             });
 
-            let filePath = pathAbsolute;
+            let filePath = srcPath;
             if (!emitFullPaths) {
                 filePath = path.relative(cwd, filePath);
             }
             //load the file text
-            const file = this.program.getFileByPathAbsolute(pathAbsolute);
+            const file = this.program.getFile(srcPath);
             //get the file's in-memory contents if available
             const lines = file?.fileContents?.split(/\r?\n/g) ?? [];
 
@@ -505,12 +506,12 @@ export class ProgramBuilder {
 
     /**
      * Remove all files from the program that are in the specified folder path
-     * @param folderPathAbsolute
+     * @param srcPath the path to the
      */
-    public removeFilesInFolder(folderPathAbsolute: string) {
+    public removeFilesInFolder(srcPath: string) {
         for (let filePath in this.program.files) {
             //if the file path starts with the parent path and the file path does not exactly match the folder path
-            if (filePath.startsWith(folderPathAbsolute) && filePath !== folderPathAbsolute) {
+            if (filePath.startsWith(srcPath) && filePath !== srcPath) {
                 this.program.removeFile(filePath);
             }
         }
diff --git a/src/Scope.spec.ts b/src/Scope.spec.ts
index 62553baf..a393b695 100644
--- a/src/Scope.spec.ts
+++ b/src/Scope.spec.ts
@@ -116,7 +116,7 @@ describe('Scope', () => {
 
             program.validate();
 
-            expect(sourceScope.getOwnFiles().map(x => x.pathAbsolute).sort()).eql([
+            expect(sourceScope.getOwnFiles().map(x => x.srcPath).sort()).eql([
                 s`${rootDir}/source/lib.brs`,
                 s`${rootDir}/source/main.brs`
             ]);
@@ -154,7 +154,7 @@ describe('Scope', () => {
             let initCallableCount = program.getScopeByName('source').getAllCallables().length;
 
             //remove the file
-            program.removeFile(file.pathAbsolute);
+            program.removeFile(file.srcPath);
             expect(program.getScopeByName('source').getAllCallables().length).to.equal(initCallableCount - 1);
         });
     });
diff --git a/src/Scope.ts b/src/Scope.ts
index c0082050..fcdca37f 100644
--- a/src/Scope.ts
+++ b/src/Scope.ts
@@ -305,11 +305,11 @@ export class Scope {
     /**
      * Get the file with the specified pkgPath
      */
-    public getFile(pathAbsolute: string) {
-        pathAbsolute = s`${pathAbsolute}`;
+    public getFile(getFile: string) {
+        getFile = s`${getFile}`;
         let files = this.getAllFiles();
         for (let file of files) {
-            if (file.pathAbsolute === pathAbsolute) {
+            if (file.srcPath === getFile) {
                 return file;
             }
         }
@@ -549,7 +549,7 @@ export class Scope {
             callables = callables.sort((a, b) => {
                 return (
                     //sort by path
-                    a.callable.file.pathAbsolute.localeCompare(b.callable.file.pathAbsolute) ||
+                    a.callable.file.srcPath.localeCompare(b.callable.file.srcPath) ||
                     //then sort by method name
                     a.callable.name.localeCompare(b.callable.name)
                 );
@@ -618,7 +618,7 @@ export class Scope {
                         relatedInformation: [{
                             message: 'Namespace declared here',
                             location: Location.create(
-                                URI.file(namespace.file.pathAbsolute).toString(),
+                                URI.file(namespace.file.srcPath).toString(),
                                 namespace.nameRange
                             )
                         }]
@@ -639,7 +639,7 @@ export class Scope {
                     relatedInformation: [{
                         message: 'Namespace declared here',
                         location: Location.create(
-                            URI.file(namespace.file.pathAbsolute).toString(),
+                            URI.file(namespace.file.srcPath).toString(),
                             namespace.nameRange
                         )
                     }]
diff --git a/src/XmlScope.spec.ts b/src/XmlScope.spec.ts
index 290d05e1..458264f1 100644
--- a/src/XmlScope.spec.ts
+++ b/src/XmlScope.spec.ts
@@ -74,7 +74,7 @@ describe('XmlScope', () => {
             let childScope = program.getScopesForFile(childXmlFile);
             let definition = childScope[0].getDefinition(childXmlFile, Position.create(1, 48));
             expect(definition).to.be.lengthOf(1);
-            expect(definition[0].uri).to.equal(util.pathToUri(parentXmlFile.pathAbsolute));
+            expect(definition[0].uri).to.equal(util.pathToUri(parentXmlFile.srcPath));
         });
     });
 
diff --git a/src/XmlScope.ts b/src/XmlScope.ts
index e852410e..8fcb68df 100644
--- a/src/XmlScope.ts
+++ b/src/XmlScope.ts
@@ -171,7 +171,7 @@ export class XmlScope extends Scope {
         ) {
             results.push({
                 range: util.createRange(0, 0, 0, 0),
-                uri: util.pathToUri(file.parentComponent.pathAbsolute)
+                uri: util.pathToUri(file.parentComponent.srcPath)
             });
         }
         return results;
diff --git a/src/bscPlugin/codeActions/CodeActionsProcessor.spec.ts b/src/bscPlugin/codeActions/CodeActionsProcessor.spec.ts
index 408dea55..be2584be 100644
--- a/src/bscPlugin/codeActions/CodeActionsProcessor.spec.ts
+++ b/src/bscPlugin/codeActions/CodeActionsProcessor.spec.ts
@@ -26,7 +26,7 @@ describe('CodeActionsProcessor', () => {
             program.validate();
             expectCodeActions(() => {
                 program.getCodeActions(
-                    file.pathAbsolute,
+                    file.srcPath,
                     //<comp|onent name="comp1">
                     util.createRange(1, 5, 1, 5)
                 );
@@ -72,7 +72,7 @@ describe('CodeActionsProcessor', () => {
             `);
             program.validate();
             const codeActions = program.getCodeActions(
-                file.pathAbsolute,
+                file.srcPath,
                 //<comp|onent name="comp1">
                 util.createRange(1, 5, 1, 5)
             );
@@ -119,7 +119,7 @@ describe('CodeActionsProcessor', () => {
 
             //we should only get each file import suggestion exactly once
             const codeActions = program.getCodeActions(
-                componentCommonFile.pathAbsolute,
+                componentCommonFile.srcPath,
                 // doSome|thing()
                 util.createRange(2, 22, 2, 22)
             );
@@ -154,7 +154,7 @@ describe('CodeActionsProcessor', () => {
 
             //there should be no code actions since this is a brs file
             const codeActions = program.getCodeActions(
-                file.pathAbsolute,
+                file.srcPath,
                 // DoSometh|ing()
                 util.createRange(2, 28, 2, 28)
             );
@@ -184,7 +184,7 @@ describe('CodeActionsProcessor', () => {
 
             expect(
                 program.getCodeActions(
-                    file.pathAbsolute,
+                    file.srcPath,
                     // new Per|son()
                     util.createRange(2, 34, 2, 34)
                 ).map(x => x.title).sort()
@@ -218,7 +218,7 @@ describe('CodeActionsProcessor', () => {
 
             expect(
                 program.getCodeActions(
-                    file.pathAbsolute,
+                    file.srcPath,
                     // new Anim|als.Cat()
                     util.createRange(2, 36, 2, 36)
                 ).map(x => x.title).sort()
diff --git a/src/bscPlugin/codeActions/CodeActionsProcessor.ts b/src/bscPlugin/codeActions/CodeActionsProcessor.ts
index d86b8b0d..bf332284 100644
--- a/src/bscPlugin/codeActions/CodeActionsProcessor.ts
+++ b/src/bscPlugin/codeActions/CodeActionsProcessor.ts
@@ -55,7 +55,7 @@ export class CodeActionsProcessor {
                     kind: CodeActionKind.QuickFix,
                     changes: [{
                         type: 'insert',
-                        filePath: this.event.file.pathAbsolute,
+                        filePath: this.event.file.srcPath,
                         position: insertPosition,
                         newText: `import "${pkgPath}"\n`
                     }]
@@ -91,7 +91,7 @@ export class CodeActionsProcessor {
     }
 
     private addMissingExtends(diagnostic: DiagnosticMessageType<'xmlComponentMissingExtendsAttribute'>) {
-        const srcPath = this.event.file.pathAbsolute;
+        const srcPath = this.event.file.srcPath;
         const { component } = (this.event.file as XmlFile).parser.ast;
         //inject new attribute after the final attribute, or after the `<component` if there are no attributes
         const pos = (component.attributes[component.attributes.length - 1] ?? component.tag).range.end;
diff --git a/src/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.ts b/src/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.ts
index 63b183f1..a5f0166a 100644
--- a/src/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.ts
+++ b/src/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.ts
@@ -33,7 +33,7 @@ describe('BrsFileSemanticTokensProcessor', () => {
         program.validate();
         expectZeroDiagnostics(program);
         expect(
-            program.getSemanticTokens(file.pathAbsolute)
+            program.getSemanticTokens(file.srcPath)
         ).to.eql([{
             range: util.createRange(7, 34, 7, 44),
             tokenType: SemanticTokenTypes.namespace
@@ -61,7 +61,7 @@ describe('BrsFileSemanticTokensProcessor', () => {
         program.validate();
         expectZeroDiagnostics(program);
         expect(
-            util.sortByRange(program.getSemanticTokens(file.pathAbsolute))
+            util.sortByRange(program.getSemanticTokens(file.srcPath))
         ).to.eql([{
             range: util.createRange(2, 22, 2, 32),
             tokenType: SemanticTokenTypes.namespace
diff --git a/src/bscPlugin/validation/ScopeValidator.ts b/src/bscPlugin/validation/ScopeValidator.ts
index 6840f0af..2cf6eec0 100644
--- a/src/bscPlugin/validation/ScopeValidator.ts
+++ b/src/bscPlugin/validation/ScopeValidator.ts
@@ -97,7 +97,7 @@ export class ScopeValidator {
                             relatedInformation: [{
                                 message: 'Enum declared here',
                                 location: Location.create(
-                                    URI.file(file.pathAbsolute).toString(),
+                                    URI.file(file.srcPath).toString(),
                                     theEnum.tokens.name.range
                                 )
                             }]
@@ -128,7 +128,7 @@ export class ScopeValidator {
         //now that we've collected all enum declarations, flag duplicates
         for (const enumLocations of enumLocationsByName.values()) {
             //sort by srcPath to keep the primary enum location consistent
-            enumLocations.sort((a, b) => a.file?.pathAbsolute?.localeCompare(b.file?.pathAbsolute));
+            enumLocations.sort((a, b) => a.file?.srcPath?.localeCompare(b.file?.srcPath));
             const primaryEnum = enumLocations.shift();
             const fullName = primaryEnum.statement.fullName;
             for (const duplicateEnumInfo of enumLocations) {
@@ -139,7 +139,7 @@ export class ScopeValidator {
                     relatedInformation: [{
                         message: 'Enum declared here',
                         location: Location.create(
-                            URI.file(primaryEnum.file.pathAbsolute).toString(),
+                            URI.file(primaryEnum.file.srcPath).toString(),
                             primaryEnum.statement.tokens.name.range
                         )
                     }]
diff --git a/src/files/BrsFile.spec.ts b/src/files/BrsFile.spec.ts
index 03208264..584f9f29 100644
--- a/src/files/BrsFile.spec.ts
+++ b/src/files/BrsFile.spec.ts
@@ -124,7 +124,7 @@ describe('BrsFile', () => {
                 end sub
             `);
             expect(() => {
-                program.getCompletions(file.pathAbsolute, util.createPosition(2, 34));
+                program.getCompletions(file.srcPath, util.createPosition(2, 34));
             }).not.to.throw;
         });
 
@@ -1720,7 +1720,7 @@ describe('BrsFile', () => {
             `);
 
             expect(
-                (await program.getHover(file.pathAbsolute, Position.create(2, 30))).contents
+                (await program.getHover(file.srcPath, Position.create(2, 30))).contents
             ).to.equal([
                 '```brightscript',
                 'function UCase(s as string) as string',
@@ -1736,7 +1736,7 @@ describe('BrsFile', () => {
             `);
 
             expect(
-                (await program.getHover(file.pathAbsolute, Position.create(2, 35))).contents
+                (await program.getHover(file.srcPath, Position.create(2, 35))).contents
             ).to.equal([
                 '```brightscript',
                 //TODO this really shouldn't be returning the global function, but it does...so make sure it doesn't crash right now.
@@ -1820,7 +1820,7 @@ describe('BrsFile', () => {
 
             //hover over log("hello")
             expect(
-                (await program.getHover(file.pathAbsolute, Position.create(5, 22))).contents
+                (await program.getHover(file.srcPath, Position.create(5, 22))).contents
             ).to.equal([
                 '```brightscript',
                 'sub log(message as string) as void',
@@ -1835,7 +1835,7 @@ describe('BrsFile', () => {
             //hover over sub ma|in()
             expect(
                 trim(
-                    (await program.getHover(file.pathAbsolute, Position.create(4, 22))).contents.toString()
+                    (await program.getHover(file.srcPath, Position.create(4, 22))).contents.toString()
                 )
             ).to.equal(trim`
                 \`\`\`brightscript
@@ -2771,7 +2771,7 @@ describe('BrsFile', () => {
         it('removes typedef link when typedef is removed', () => {
             const typedef = program.setFile<BrsFile>('source/main.d.bs', ``);
             const file = program.setFile<BrsFile>('source/main.brs', ``);
-            program.removeFile(typedef.pathAbsolute);
+            program.removeFile(typedef.srcPath);
             expect(file.typedefFile).to.be.undefined;
         });
     });
diff --git a/src/files/BrsFile.ts b/src/files/BrsFile.ts
index 127eb8dc..9289076e 100644
--- a/src/files/BrsFile.ts
+++ b/src/files/BrsFile.ts
@@ -34,18 +34,18 @@ import { CommentFlagProcessor } from '../CommentFlagProcessor';
  */
 export class BrsFile {
     constructor(
-        public pathAbsolute: string,
+        public srcPath: string,
         /**
          * The full pkg path to this file
          */
         public pkgPath: string,
         public program: Program
     ) {
-        this.pathAbsolute = s`${this.pathAbsolute}`;
+        this.srcPath = s`${this.srcPath}`;
         this.pkgPath = s`${this.pkgPath}`;
         this.dependencyGraphKey = this.pkgPath.toLowerCase();
 
-        this.extension = util.getExtension(this.pathAbsolute);
+        this.extension = util.getExtension(this.srcPath);
 
         //all BrighterScript files need to be transpiled
         if (this.extension?.endsWith('.bs')) {
@@ -54,7 +54,7 @@ export class BrsFile {
         }
         this.isTypedef = this.extension === '.d.bs';
         if (!this.isTypedef) {
-            this.typedefKey = util.getTypedefPath(this.pathAbsolute);
+            this.typedefKey = util.getTypedefPath(this.srcPath);
         }
 
         //global file doesn't have a program, so only resolve typedef info if we have a program
@@ -63,6 +63,17 @@ export class BrsFile {
         }
     }
 
+    /**
+     * The absolute path to the source location for this file
+     * @deprecated use `srcPath` instead
+     */
+    public get pathAbsolute() {
+        return this.srcPath;
+    }
+    public set pathAbsolute(value) {
+        this.srcPath = value;
+    }
+
     /**
      * The parseMode used for the parser for this file
      */
@@ -208,7 +219,7 @@ export class BrsFile {
      * Find and set the typedef variables (if a matching typedef file exists)
      */
     private resolveTypedef() {
-        this.typedefFile = this.program.getFileByPathAbsolute<BrsFile>(this.typedefKey);
+        this.typedefFile = this.program.getFile<BrsFile>(this.typedefKey);
         this.hasTypedef = !!this.typedefFile;
     }
 
@@ -252,7 +263,7 @@ export class BrsFile {
             }
 
             //tokenize the input file
-            let lexer = this.program.logger.time(LogLevel.debug, ['lexer.lex', chalk.green(this.pathAbsolute)], () => {
+            let lexer = this.program.logger.time(LogLevel.debug, ['lexer.lex', chalk.green(this.srcPath)], () => {
                 return Lexer.scan(fileContents, {
                     includeWhitespace: false
                 });
@@ -266,7 +277,7 @@ export class BrsFile {
             //TODO preprocessor should go away in favor of the AST handling this internally (because it affects transpile)
             //currently the preprocessor throws exceptions on syntax errors...so we need to catch it
             try {
-                this.program.logger.time(LogLevel.debug, ['preprocessor.process', chalk.green(this.pathAbsolute)], () => {
+                this.program.logger.time(LogLevel.debug, ['preprocessor.process', chalk.green(this.srcPath)], () => {
                     preprocessor.process(lexer.tokens, this.program.getManifest());
                 });
             } catch (error: any) {
@@ -279,7 +290,7 @@ export class BrsFile {
             //if the preprocessor generated tokens, use them.
             let tokens = preprocessor.processedTokens.length > 0 ? preprocessor.processedTokens : lexer.tokens;
 
-            this.program.logger.time(LogLevel.debug, ['parser.parse', chalk.green(this.pathAbsolute)], () => {
+            this.program.logger.time(LogLevel.debug, ['parser.parse', chalk.green(this.srcPath)], () => {
                 this._parser = Parser.parse(tokens, {
                     mode: this.parseMode,
                     logger: this.program.logger
@@ -1082,7 +1093,7 @@ export class BrsFile {
             if (!location && statement.getName(ParseMode.BrighterScript).toLowerCase() === namespaceName) {
                 const namespaceItemStatementHandler = (statement: ClassStatement | FunctionStatement) => {
                     if (!location && statement.name.text.toLowerCase() === endName) {
-                        const uri = util.pathToUri(file.pathAbsolute);
+                        const uri = util.pathToUri(file.srcPath);
                         location = Location.create(uri, statement.range);
                     }
                 };
@@ -1363,7 +1374,7 @@ export class BrsFile {
         }
 
         const name = statement.getName(ParseMode.BrighterScript);
-        const uri = util.pathToUri(this.pathAbsolute);
+        const uri = util.pathToUri(this.srcPath);
         const symbol = SymbolInformation.create(name, symbolKind, statement.range, uri, containerStatement?.getName(ParseMode.BrighterScript));
         symbols.push(symbol);
         return symbols;
@@ -1399,7 +1410,7 @@ export class BrsFile {
                 //to only get functions defined in interface methods
                 const callable = scope.getAllCallables().find((c) => c.callable.name.toLowerCase() === textToSearchFor); // eslint-disable-line @typescript-eslint/no-loop-func
                 if (callable) {
-                    results.push(Location.create(util.pathToUri((callable.callable.file as BrsFile).pathAbsolute), callable.callable.functionStatement.range));
+                    results.push(Location.create(util.pathToUri((callable.callable.file as BrsFile).srcPath), callable.callable.functionStatement.range));
                 }
             }
             return results;
@@ -1412,7 +1423,7 @@ export class BrsFile {
                 const nameParts = cs.parentClassName.getNameParts();
                 let extendedClass = this.getClassFileLink(nameParts[nameParts.length - 1], nameParts.slice(0, -1).join('.'));
                 if (extendedClass) {
-                    results.push(Location.create(util.pathToUri(extendedClass.file.pathAbsolute), extendedClass.item.range));
+                    results.push(Location.create(util.pathToUri(extendedClass.file.srcPath), extendedClass.item.range));
                 }
             }
             return results;
@@ -1436,14 +1447,14 @@ export class BrsFile {
             for (const varDeclaration of functionScope.variableDeclarations) {
                 //we found a variable declaration with this token text!
                 if (varDeclaration.name.toLowerCase() === textToSearchFor) {
-                    const uri = util.pathToUri(this.pathAbsolute);
+                    const uri = util.pathToUri(this.srcPath);
                     results.push(Location.create(uri, varDeclaration.nameRange));
                 }
             }
             if (this.tokenFollows(token, TokenKind.Goto)) {
                 for (const label of functionScope.labelStatements) {
                     if (label.name.toLocaleLowerCase() === textToSearchFor) {
-                        const uri = util.pathToUri(this.pathAbsolute);
+                        const uri = util.pathToUri(this.srcPath);
                         results.push(Location.create(uri, label.nameRange));
                     }
                 }
@@ -1468,7 +1479,7 @@ export class BrsFile {
                 }
                 const statementHandler = (statement: FunctionStatement) => {
                     if (statement.getName(this.parseMode).toLowerCase() === textToSearchFor) {
-                        const uri = util.pathToUri(file.pathAbsolute);
+                        const uri = util.pathToUri(file.srcPath);
                         results.push(Location.create(uri, statement.range));
                     }
                 };
@@ -1488,12 +1499,12 @@ export class BrsFile {
         //get class fields and members
         const statementHandler = (statement: ClassMethodStatement) => {
             if (statement.getName(file.parseMode).toLowerCase() === textToSearchFor) {
-                results.push(Location.create(util.pathToUri(file.pathAbsolute), statement.range));
+                results.push(Location.create(util.pathToUri(file.srcPath), statement.range));
             }
         };
         const fieldStatementHandler = (statement: ClassFieldStatement) => {
             if (statement.name.text.toLowerCase() === textToSearchFor) {
-                results.push(Location.create(util.pathToUri(file.pathAbsolute), statement.range));
+                results.push(Location.create(util.pathToUri(file.srcPath), statement.range));
             }
         };
         file.parser.ast.walk(createVisitor({
@@ -1745,7 +1756,7 @@ export class BrsFile {
                 file.ast.walk(createVisitor({
                     VariableExpression: (e) => {
                         if (e.name.text.toLowerCase() === searchFor) {
-                            locations.push(Location.create(util.pathToUri(file.pathAbsolute), e.range));
+                            locations.push(Location.create(util.pathToUri(file.srcPath), e.range));
                         }
                     }
                 }), {
@@ -1790,7 +1801,7 @@ export class BrsFile {
     public getTypedef() {
         const state = new BrsTranspileState(this);
         const typedef = this.ast.getTypedef(state);
-        const programNode = new SourceNode(null, null, this.pathAbsolute, typedef);
+        const programNode = new SourceNode(null, null, this.srcPath, typedef);
         return programNode.toString();
     }
 
diff --git a/src/files/XmlFile.spec.ts b/src/files/XmlFile.spec.ts
index c67013bc..3c9025dd 100644
--- a/src/files/XmlFile.spec.ts
+++ b/src/files/XmlFile.spec.ts
@@ -409,7 +409,7 @@ describe('XmlFile', () => {
                 </component>
             `);
 
-            expect(program.getCompletions(xmlFile.pathAbsolute, Position.create(1, 1))).to.be.empty;
+            expect(program.getCompletions(xmlFile.srcPath, Position.create(1, 1))).to.be.empty;
         });
     });
 
@@ -972,7 +972,7 @@ describe('XmlFile', () => {
         program.plugins.add({
             name: 'Xml diagnostic test',
             afterFileParse: (file) => {
-                if (file.pathAbsolute.endsWith('.xml')) {
+                if (file.srcPath.endsWith('.xml')) {
                     file.addDiagnostics([{
                         file: file,
                         message: 'Test diagnostic',
@@ -1150,7 +1150,7 @@ describe('XmlFile', () => {
             expect(functionNames).not.to.include('logBrs');
 
             //remove the typdef file
-            program.removeFile(typedef.pathAbsolute);
+            program.removeFile(typedef.srcPath);
 
             program.validate();
             functionNames = scope.getOwnCallables().map(x => x.callable.name);
diff --git a/src/files/XmlFile.ts b/src/files/XmlFile.ts
index e172e35c..cfc2dc3d 100644
--- a/src/files/XmlFile.ts
+++ b/src/files/XmlFile.ts
@@ -19,14 +19,14 @@ import { TranspileState } from '../parser/TranspileState';
 
 export class XmlFile {
     constructor(
-        public pathAbsolute: string,
+        public srcPath: string,
         /**
          * The absolute path to the file, relative to the pkg
          */
         public pkgPath: string,
         public program: Program
     ) {
-        this.extension = path.extname(pathAbsolute).toLowerCase();
+        this.extension = path.extname(this.srcPath).toLowerCase();
 
         this.possibleCodebehindPkgPaths = [
             this.pkgPath.replace('.xml', '.bs'),
@@ -34,6 +34,17 @@ export class XmlFile {
         ];
     }
 
+    /**
+     * The absolute path to the source location for this file
+     * @deprecated use `srcPath` instead
+     */
+    public get pathAbsolute() {
+        return this.srcPath;
+    }
+    public set pathAbsolute(value) {
+        this.srcPath = value;
+    }
+
     private cache = new Cache();
 
     /**
@@ -408,9 +419,10 @@ export class XmlFile {
      * Get the parent component (the component this component extends)
      */
     public get parentComponent() {
-        return this.cache.getOrAdd('parent', () => {
-            return this.program.getComponent(this.parentComponentName?.text)?.file ?? null;
+        const result = this.cache.getOrAdd('parent', () => {
+            return this.program.getComponent(this.parentComponentName?.text)?.file;
         });
+        return result;
     }
 
     public getHover(position: Position): Hover { //eslint-disable-line
@@ -501,7 +513,7 @@ export class XmlFile {
      * Convert the brightscript/brighterscript source code into valid brightscript
      */
     public transpile(): CodeWithSourceMap {
-        const state = new TranspileState(this.pathAbsolute, this.program.options);
+        const state = new TranspileState(this.srcPath, this.program.options);
 
         const extraImportScripts = this.getMissingImportsForTranspile().map(uri => {
             const script = new SGScript();
diff --git a/src/globalCallables.spec.ts b/src/globalCallables.spec.ts
index ae03d552..38c836d9 100644
--- a/src/globalCallables.spec.ts
+++ b/src/globalCallables.spec.ts
@@ -61,7 +61,7 @@ describe('globalCallables', () => {
             end sub
         `);
         program.validate();
-        const hover = await program.getHover(file.pathAbsolute, util.createPosition(2, 25));
+        const hover = await program.getHover(file.srcPath, util.createPosition(2, 25));
         expect(
             hover.contents.toString().replace('\r\n', '\n')
         ).to.eql([
diff --git a/src/interfaces.ts b/src/interfaces.ts
index dd1d8226..7ea71e48 100644
--- a/src/interfaces.ts
+++ b/src/interfaces.ts
@@ -130,7 +130,7 @@ export interface File {
      * The absolute path to the file, relative to the pkg
      */
     pkgPath: string;
-    pathAbsolute: string;
+    srcPath: string;
     getDiagnostics(): BsDiagnostic[];
 }
 
@@ -318,7 +318,7 @@ export interface TypedefProvider {
 
 export type TranspileResult = Array<(string | SourceNode)>;
 
-export type FileResolver = (pathAbsolute: string) => string | undefined | Thenable<string | undefined> | void;
+export type FileResolver = (srcPath: string) => string | undefined | Thenable<string | undefined> | void;
 
 export interface ExpressionInfo {
     expressions: Expression[];
diff --git a/src/parser/BrsTranspileState.ts b/src/parser/BrsTranspileState.ts
index d83e015a..ef2b9845 100644
--- a/src/parser/BrsTranspileState.ts
+++ b/src/parser/BrsTranspileState.ts
@@ -7,7 +7,7 @@ export class BrsTranspileState extends TranspileState {
     public constructor(
         public file: BrsFile
     ) {
-        super(file.pathAbsolute, file.program.options);
+        super(file.srcPath, file.program.options);
         this.bslibPrefix = this.file.program.bslibPrefix;
     }
 
diff --git a/src/util.ts b/src/util.ts
index 6c05113f..c846de7a 100644
--- a/src/util.ts
+++ b/src/util.ts
@@ -179,7 +179,7 @@ export class Util {
                 let diagnostic = {
                     ...DiagnosticMessages.bsConfigJsonHasSyntaxErrors(printParseErrorCode(parseErrors[0].error)),
                     file: {
-                        pathAbsolute: configFilePath
+                        srcPath: configFilePath
                     },
                     range: this.getRangeFromOffsetLength(projectFileContents, err.offset, err.length)
                 } as BsDiagnostic;
@@ -436,16 +436,16 @@ export class Util {
 
     /**
      * Compute the relative path from the source file to the target file
-     * @param pkgSourcePathAbsolute  - the absolute path to the source relative to the package location
-     * @param pkgTargetPathAbsolute  - the absolute path ro the target relative to the package location
+     * @param pkgSrcPath  - the absolute path to the source, where cwd is the package location
+     * @param pkgTargetPath  - the absolute path to the target, where cwd is the package location
      */
-    public getRelativePath(pkgSourcePathAbsolute: string, pkgTargetPathAbsolute: string) {
-        pkgSourcePathAbsolute = path.normalize(pkgSourcePathAbsolute);
-        pkgTargetPathAbsolute = path.normalize(pkgTargetPathAbsolute);
+    public getRelativePath(pkgSrcPath: string, pkgTargetPath: string) {
+        pkgSrcPath = path.normalize(pkgSrcPath);
+        pkgTargetPath = path.normalize(pkgTargetPath);
 
         //break by path separator
-        let sourceParts = pkgSourcePathAbsolute.split(path.sep);
-        let targetParts = pkgTargetPathAbsolute.split(path.sep);
+        let sourceParts = pkgSrcPath.split(path.sep);
+        let targetParts = pkgTargetPath.split(path.sep);
 
         let commonParts = [] as string[];
         //find their common root
@@ -615,8 +615,8 @@ export class Util {
     /**
      * Given a file path, convert it to a URI string
      */
-    public pathToUri(pathAbsolute: string) {
-        return URI.file(pathAbsolute).toString();
+    public pathToUri(filePath: string) {
+        return URI.file(filePath).toString();
     }
 
     /**
diff --git a/src/validators/ClassValidator.ts b/src/validators/ClassValidator.ts
index 02d1c53a..8b3a8eef 100644
--- a/src/validators/ClassValidator.ts
+++ b/src/validators/ClassValidator.ts
@@ -99,7 +99,7 @@ export class BsClassValidator {
                     range: classStatement.name.range,
                     relatedInformation: [{
                         location: Location.create(
-                            URI.file(nonNamespaceClass.file.pathAbsolute).toString(),
+                            URI.file(nonNamespaceClass.file.srcPath).toString(),
                             nonNamespaceClass.name.range
                         ),
                         message: 'Original class declared here'
@@ -349,7 +349,7 @@ export class BsClassValidator {
                         range: classStatement.name.range,
                         relatedInformation: [{
                             location: Location.create(
-                                URI.file(alreadyDefinedClass.file.pathAbsolute).toString(),
+                                URI.file(alreadyDefinedClass.file.srcPath).toString(),
                                 this.classes.get(lowerName).range
                             ),
                             message: ''


Test patch:
diff --git a/src/files/tests/imports.spec.ts b/src/files/tests/imports.spec.ts
index 8e87ec47..415e038d 100644
--- a/src/files/tests/imports.spec.ts
+++ b/src/files/tests/imports.spec.ts
@@ -53,9 +53,9 @@ describe('import statements', () => {
                 return true
             end function
         `);
-        let files = Object.keys(program.files).map(x => program.getFileByPathAbsolute(x)).filter(x => !!x).map(x => {
+        let files = Object.keys(program.files).map(x => program.getFile(x)).filter(x => !!x).map(x => {
             return {
-                src: x.pathAbsolute,
+                src: x.srcPath,
                 dest: x.pkgPath
             };
         });
diff --git a/src/testHelpers.spec.ts b/src/testHelpers.spec.ts
index ffefca05..3d276b8f 100644
--- a/src/testHelpers.spec.ts
+++ b/src/testHelpers.spec.ts
@@ -90,8 +90,8 @@ export function expectZeroDiagnostics(arg: DiagnosticCollection) {
         for (const diagnostic of diagnostics) {
             //escape any newlines
             diagnostic.message = diagnostic.message.replace(/\r/g, '\\r').replace(/\n/g, '\\n');
-            message += `\n        • bs${diagnostic.code} "${diagnostic.message}" at ${diagnostic.file?.pathAbsolute ?? ''}#(${diagnostic.range.start.line}:${diagnostic.range.start.character})-(${diagnostic.range.end.line}:${diagnostic.range.end.character})`;
-            //print the line containing the error (if we can find it)
+            message += `\n        • bs${diagnostic.code} "${diagnostic.message}" at ${diagnostic.file?.srcPath ?? ''}#(${diagnostic.range.start.line}:${diagnostic.range.start.character})-(${diagnostic.range.end.line}:${diagnostic.range.end.character})`;
+            //print the line containing the error (if we can find it)srcPath
             const line = diagnostic.file?.fileContents?.split(/\r?\n/g)?.[diagnostic.range.start.line];
             if (line) {
                 message += '\n' + getDiagnosticLine(diagnostic, line, chalk.red);