Skip to content

Commit

Permalink
Source root (#134)
Browse files Browse the repository at this point in the history
* Working on source root

* Add test

* Fix sourcemap bug for non-bs files.

* Fix spec to test bs and brs files

* update docs for sourceRoot

* fix lint issue.
  • Loading branch information
TwitchBronBron authored Jul 6, 2020
1 parent 9be3c08 commit e5b73ca
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 15 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ These are the options available in the `bsconfig.json` file.
```
- **autoImportComponentScript**: `bool` - BrighterScript only: will automatically import a script at transpile-time for a component with the same name if it exists.
- **sourceRoot*: `string` - Override the root directory path where debugger should locate the source files. The location will be embedded in the source map to help debuggers locate the original source files. This only applies to files found within rootDir. This is useful when you want to preprocess files before passing them to BrighterScript, and want a debugger to open the original files.
## Ignore errors and warnings on a per-line basis
In addition to disabling an entire class of errors in `bsconfig.json` by using `ignoreErrorCodes`, you may also disable errors for a subset of the complier rules within a file with the following comment flags:
Expand Down
4 changes: 4 additions & 0 deletions bsconfig.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,10 @@
"debug",
"trace"
]
},
"sourceRoot": {
"description": "Override the root directory path where debugger should locate the source files. The location will be embedded in the source map to help debuggers locate the original source files. This only applies to files found within rootDir. This is useful when you want to preprocess files before passing them to BrighterScript, and want a debugger to open the original files.",
"type": "string"
}
}
}
7 changes: 7 additions & 0 deletions src/BsConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,11 @@ export interface BsConfig {
* @default LogLevel.log
*/
logLevel?: LogLevel;
/**
* Override the path to source files in source maps. Use this if you have a preprocess step and want
* to ensure the source maps point to the original location.
* This will only alter source maps for files within rootDir. Any files found outside of rootDir will not
* have their source maps changed.
*/
sourceRoot?: string;
}
52 changes: 52 additions & 0 deletions src/Program.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1381,4 +1381,56 @@ describe('Program', () => {
expect(fsExtra.pathExistsSync(s`${stagingFolderPath}/source/bslib.brs`)).is.true;
});

describe('transpile', () => {
it('uses sourceRoot when provided for brs files', async () => {
let sourceRoot = s`${tmpPath}/sourceRootFolder`;
program = new Program({
rootDir: rootDir,
stagingFolderPath: stagingFolderPath,
sourceRoot: sourceRoot
});
await program.addOrReplaceFile('source/main.brs', `
sub main()
end sub
`);
await program.transpile([{
src: s`${rootDir}/source/main.brs`,
dest: s`source/main.brs`
}], stagingFolderPath);

let contents = fsExtra.readFileSync(s`${stagingFolderPath}/source/main.brs.map`).toString();
let map = JSON.parse(contents);
expect(
s`${map.sources[0]}`
).to.eql(
s`${sourceRoot}/source/main.brs`
);
});

it('uses sourceRoot when provided for bs files', async () => {
let sourceRoot = s`${tmpPath}/sourceRootFolder`;
program = new Program({
rootDir: rootDir,
stagingFolderPath: stagingFolderPath,
sourceRoot: sourceRoot
});
await program.addOrReplaceFile('source/main.bs', `
sub main()
end sub
`);
await program.transpile([{
src: s`${rootDir}/source/main.bs`,
dest: s`source/main.bs`
}], stagingFolderPath);

let contents = fsExtra.readFileSync(s`${stagingFolderPath}/source/main.brs.map`).toString();
let map = JSON.parse(contents);
expect(
s`${map.sources[0]}`
).to.eql(
s`${sourceRoot}/source/main.bs`
);
});
});

});
1 change: 1 addition & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ let args = [
{ name: 'root-dir', type: String, description: 'Path to the root of your project files (where the manifest lives). Defaults to current directory.' },
{ name: 'staging-folder-path', type: String, description: 'The path where the files should be staged (right before being zipped up).' },
{ name: 'username', type: String, description: 'The username for deploying to a Roku. Defaults to "rokudev".' },
{ name: 'source-root', type: String, description: 'Override the root directory path where debugger should locate the source files. The location will be embedded in the source map to help debuggers locate the original source files. This only applies to files found within rootDir. This is useful when you want to preprocess files before passing them to BrighterScript, and want a debugger to open the original files.' },
{ name: 'watch', type: Boolean, description: 'Watch input files.' }
];
const options = commandLineArgs(args, { camelCase: true });
Expand Down
7 changes: 3 additions & 4 deletions src/files/BrsFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -985,26 +985,25 @@ export class BrsFile {
* Convert the brightscript/brighterscript source code into valid brightscript
*/
public transpile() {
const state = new TranspileState(this);
if (this.needsTranspiled) {
const state = new TranspileState(this);
let programNode = new SourceNode(null, null, this.pathAbsolute, this.ast.transpile(state));
let result = programNode.toStringWithSourceMap({
file: this.pathAbsolute
});
return result;
} else {
//create a sourcemap
//create a source map from the original source code
let chunks = [] as (SourceNode | string)[];
let lines = this.fileContents.split(/\r?\n/g);
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
let line = lines[lineIndex];
chunks.push(
lineIndex > 0 ? '\n' : '',
new SourceNode(lineIndex + 1, 0, this.pathAbsolute, line)
new SourceNode(lineIndex + 1, 0, state.pathAbsolute, line)
);
}
return new SourceNode(null, null, this.pathAbsolute, chunks).toStringWithSourceMap();
return new SourceNode(null, null, state.pathAbsolute, chunks).toStringWithSourceMap();
}
}

Expand Down
29 changes: 18 additions & 11 deletions src/parser/TranspileState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,30 @@ export class TranspileState {
file: BrsFile
) {
this.file = file;

//if a sourceRoot is specified, use that instead of the rootDir
if (this.file.program.options.sourceRoot) {
this.pathAbsolute = this.file.pathAbsolute.replace(
this.file.program.options.rootDir,
this.file.program.options.sourceRoot
);
} else {
this.pathAbsolute = this.file.pathAbsolute;
}
}

/**
* The BrsFile that is currently being transpiled
*/
file: BrsFile;
/**
* the path for this file relative to the root of the output package
*/
get pkgPath() {
return this.file.pkgPath;
}
public file: BrsFile;

/**
* the absolute path to the source location of this file
* The absolute path to the source location of this file. If sourceRoot is specified,
* this path will be full path to the file in sourceRoot instead of rootDir.
* If the file resides outside of rootDir, then no changes will be made to this path.
*/
get pathAbsolute() {
return this.file.pathAbsolute;
}
public pathAbsolute: string;

/**
* The number of active parent blocks for the current location of the state.
*/
Expand Down
1 change: 1 addition & 0 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ export class Util {
config.diagnosticFilters = config.diagnosticFilters ?? [];
config.autoImportComponentScript = config.autoImportComponentScript === true ? true : false;
config.showDiagnosticsInConsole = config.showDiagnosticsInConsole === false ? false : true;
config.sourceRoot = config.sourceRoot ? standardizePath(config.sourceRoot) : undefined;
if (typeof config.logLevel === 'string') {
config.logLevel = LogLevel[(config.logLevel as string).toLowerCase()];
}
Expand Down

0 comments on commit e5b73ca

Please sign in to comment.