Skip to content

Commit

Permalink
Implementation changes
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonpaulos committed Dec 11, 2023
1 parent 7c5a1ed commit 00f7a19
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 82 deletions.
39 changes: 21 additions & 18 deletions extension/src/fileAccessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,47 @@ import { FileAccessor } from '../../src/common';
export const workspaceFileAccessor: FileAccessor = {
isWindows: typeof process !== 'undefined' && process.platform === 'win32',
readFile(path: string): Promise<Uint8Array> {
const uri = pathToUri(path);
const uri = vscode.Uri.file(path);
return thenableToPromise(vscode.workspace.fs.readFile(uri));
},
writeFile(path: string, contents: Uint8Array): Promise<void> {
const uri = pathToUri(path);
const uri = vscode.Uri.file(path);
return thenableToPromise(vscode.workspace.fs.writeFile(uri, contents));
},
basename(path: string): string {
const uri = pathToUri(path);
const uri = vscode.Uri.file(path);
const lastSlash = uri.path.lastIndexOf('/');
if (lastSlash === -1) {
return path;
}
return uri.path.substring(lastSlash + 1);
},
filePathRelativeTo: function (base: string, filePath: string): string {
filePathRelativeTo(base: string, filePath: string): string {
// Check if filePath is an absolute path
if (this.isWindows) {
if (filePath.match(/^[a-zA-Z]:\\/)) {
return filePath;
}
} else {
if (filePath.startsWith('/')) {
return filePath;
}
}

// Create a Uri object with the base path
const baseUri = vscode.Uri.file(base);
let baseUri = vscode.Uri.file(base);
if (!baseUri.path.endsWith('/')) {
// If the base path is not a directory, get its parent directory
baseUri = vscode.Uri.joinPath(baseUri, '..');
}

// Resolve the file path against the base Uri
const fullUri = vscode.Uri.joinPath(baseUri, filePath);

// Extract the path from the Uri
const resolvedPath = fullUri.path;

// Normalize the resolved path
return resolvedPath.replace(/\\/g, '/');
return fullUri.fsPath;
},
};

function pathToUri(path: string) {
try {
return vscode.Uri.file(path);
} catch (e) {
return vscode.Uri.parse(path, true);
}
}

function thenableToPromise<T>(t: Thenable<T>): Promise<T> {
return new Promise((resolve, reject) => {
t.then(resolve, reject);
Expand Down
18 changes: 1 addition & 17 deletions src/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,22 +121,6 @@ export class ByteArrayMap<T> {
}
}

export function filePathRelativeTo(base: string, filePath: string): string {
// Normalize the base path to convert any Windows backslashes to forward slashes
// This is necessary because the URL object expects forward slashes
const normalizedBase = base.replace(/\\/g, '/');

// Create a URL object with the file protocol and the normalized base path
const baseURL = new URL(normalizedBase, 'file:///');

// Resolve the file path against the base URL
const fullURL = new URL(filePath, baseURL);

// Convert the URL back to a local file path
// On Windows, this will correctly handle the drive letter and convert to backslashes
return fullURL.pathname;
}

interface ProgramSourceEntryFile {
'txn-group-sources': ProgramSourceEntry[];
}
Expand Down Expand Up @@ -187,7 +171,7 @@ export class ProgramSourceDescriptor {
originFile: string,
data: ProgramSourceEntry,
): Promise<ProgramSourceDescriptor> {
const sourcemapFileLocation = filePathRelativeTo(
const sourcemapFileLocation = fileAccessor.filePathRelativeTo(
originFile,
data['sourcemap-location'],
);
Expand Down
24 changes: 8 additions & 16 deletions src/node/fileAccessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,14 @@ export const nodeFileAccessor: FileAccessor = {
basename(path: string): string {
return basename(path);
},
filePathRelativeTo: function (base: string, filePath: string): string {
// Create a URL object with the file protocol and the base path
const baseURL = new URL(base, 'file:///');

// Resolve the file path against the base URL
const fullURL = new URL(filePath, baseURL);

// Convert the URL back to a local file path
// On Windows, this will correctly handle the drive letter and convert to backslashes
const resolvedPath = path.resolve(fullURL.pathname);

// Normalize the resolved path to ensure it's in the correct format for the current OS
if (this.isWindows) {
return resolvedPath.replace(/\//g, '\\');
} else {
return resolvedPath.replace(/\\/g, '/');
filePathRelativeTo(base: string, filePath: string): string {
if (path.isAbsolute(filePath)) {
return filePath;
}
if (!base.endsWith(path.sep)) {
// If the base path is not a directory, get its parent directory
base = path.dirname(base);
}
return path.join(base, filePath);
},
};
31 changes: 0 additions & 31 deletions tests/common/utils.test.ts

This file was deleted.

73 changes: 73 additions & 0 deletions tests/node/fileAccessor.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import * as assert from 'assert';
import * as path from 'path';
import { nodeFileAccessor } from '../../src/node';

describe('Node FileAccessor Tests', () => {
describe('filePathRelativeTo', () => {
function getExampleAbsolutePathFor(filename: string): string {
let base: string;
if (nodeFileAccessor.isWindows) {
base = 'C:\\somelongpath\\sources';
} else {
base = '/somelongpath/sources';
}
return path.join(base, filename);
}

interface TestCase {
description: string;
base: string;
filePath: string;
expected: string;
}

const testCases: TestCase[] = [
{
description: 'should be correct when the base path is a file',
base: getExampleAbsolutePathFor('sources.json'),
filePath: 'slot-machine/slot-machine.teal.tok.map',
expected: getExampleAbsolutePathFor(
['slot-machine', 'slot-machine.teal.tok.map'].join(path.sep),
),
},
{
description: 'should be correct when the relative path contains ..',
base: getExampleAbsolutePathFor('sources.json'),
filePath: '../slot-machine/slot-machine.teal.tok.map',
expected: getExampleAbsolutePathFor(
['..', 'slot-machine', 'slot-machine.teal.tok.map'].join(path.sep),
),
},
{
description: 'should be correct when the base path is a directory',
base: getExampleAbsolutePathFor('directory' + path.sep),
filePath: 'slot-machine/slot-machine.teal.tok.map',
expected: getExampleAbsolutePathFor(
['directory', 'slot-machine', 'slot-machine.teal.tok.map'].join(
path.sep,
),
),
},
{
description: 'should be correct when the file path is absolute',
base: 'i do not matter',
filePath: getExampleAbsolutePathFor(
'slot-machine/slot-machine.teal.tok.map',
),
expected: getExampleAbsolutePathFor(
'slot-machine/slot-machine.teal.tok.map',
),
},
];

for (const testCase of testCases) {
it(testCase.description, () => {
const result = nodeFileAccessor.filePathRelativeTo(
testCase.base,
testCase.filePath,
);
assert.strictEqual(result, testCase.expected);
});
}
});
});

0 comments on commit 00f7a19

Please sign in to comment.