Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transpile files added after start of transpile cycle #578

Merged
merged 2 commits into from
Apr 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions src/Program.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1717,6 +1717,51 @@ describe('Program', () => {

describe('transpile', () => {

it('detects and transpiles files added between beforeProgramTranspile and afterProgramTranspile', async () => {
program.setFile('source/main.bs', trim`
sub main()
print "hello world"
end sub
`);
program.plugins.add({
name: 'TestPlugin',
beforeFileTranspile: (event) => {
if (isBrsFile(event.file)) {
//add lib1
if (event.outputPath.endsWith('main.brs')) {
event.program.setFile('source/lib1.bs', `
sub lib1()
end sub
`);
}
//add lib2 (this should happen during the next cycle of "catch missing files" cycle
if (event.outputPath.endsWith('main.brs')) {
//add another file
event.program.setFile('source/lib2.bs', `
sub lib2()
end sub
`);
}
}
}
});
await program.transpile([], stagingFolderPath);
//our new files should exist
expect(
fsExtra.readFileSync(`${stagingFolderPath}/source/lib1.brs`).toString()
).to.eql(trim`
sub lib1()
end sub
`);
//our changes should be there
expect(
fsExtra.readFileSync(`${stagingFolderPath}/source/lib2.brs`).toString()
).to.eql(trim`
sub lib2()
end sub
`);
});

it('sets needsTranspiled=true when there is at least one edit', async () => {
program.setFile('source/main.brs', trim`
sub main()
Expand Down
58 changes: 45 additions & 13 deletions src/Program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1267,6 +1267,7 @@ export class Program {
const editor = new AstEditor();

this.plugins.emit('beforeFileTranspile', {
program: this,
file: file,
outputPath: outputPath,
editor: editor
Expand All @@ -1288,6 +1289,7 @@ export class Program {
}

const event: AfterFileTranspileEvent = {
program: this,
file: file,
outputPath: outputPath,
editor: editor,
Expand Down Expand Up @@ -1316,7 +1318,7 @@ export class Program {
return collection;
}, {});

const entries = Object.values(this.files).map(file => {
const getOutputPath = (file: BscFile) => {
let filePathObj = mappedFileEntries[s`${file.pathAbsolute}`];
if (!filePathObj) {
//this file has been added in-memory, from a plugin, for example
Expand All @@ -1330,24 +1332,20 @@ export class Program {
let outputPath = filePathObj.dest.replace(/\.bs$/gi, '.brs');
//prepend the staging folder path
outputPath = s`${stagingFolderPath}/${outputPath}`;
return {
file: file,
outputPath: outputPath
};
});
return outputPath;
};

const astEditor = new AstEditor();
const processedFiles = new Set<File>();

this.plugins.emit('beforeProgramTranspile', this, entries, astEditor);
const transpileFile = async (file: BscFile, outputPath?: string) => {
//mark this file as processed so we don't do it again
processedFiles.add(file);

const promises = entries.map(async (entry) => {
//skip transpiling typedef files
if (isBrsFile(entry.file) && entry.file.isTypedef) {
if (isBrsFile(file) && file.isTypedef) {
return;
}

const { file, outputPath } = entry;

const fileTranspileResult = this._getTranspiledFileContents(file, outputPath);

//make sure the full dir path exists
Expand All @@ -1366,14 +1364,48 @@ export class Program {
const typedefPath = outputPath.replace(/\.brs$/i, '.d.bs');
await fsExtra.writeFile(typedefPath, fileTranspileResult.typedef);
}
};

const entries = Object.values(this.files).map(file => {
return {
file: file,
outputPath: getOutputPath(file)
};
});

const astEditor = new AstEditor();

this.plugins.emit('beforeProgramTranspile', this, entries, astEditor);

let promises = entries.map(async (entry) => {
return transpileFile(entry.file, entry.outputPath);
});

//if there's no bslib file already loaded into the program, copy it to the staging directory
if (!this.getFileByPkgPath(bslibAliasedRokuModulesPkgPath) && !this.getFileByPkgPath(s`source/bslib.brs`)) {
if (!this.getFile(bslibAliasedRokuModulesPkgPath) && !this.getFile(s`source/bslib.brs`)) {
promises.push(util.copyBslibToStaging(stagingFolderPath));
}
await Promise.all(promises);

//transpile any new files that plugins added since the start of this transpile process
do {
promises = [];
for (const key in this.files) {
const file = this.files[key];
//this is a new file
if (!processedFiles.has(file)) {
promises.push(
transpileFile(file, getOutputPath(file))
);
}
}
if (promises.length > 0) {
this.logger.info(`Transpiling ${promises.length} new files`);
await Promise.all(promises);
}
}
while (promises.length > 0);

this.plugins.emit('afterProgramTranspile', this, entries, astEditor);
astEditor.undoAll();
}
Expand Down
5 changes: 5 additions & 0 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ export interface OnScopeValidateEvent {
export type Editor = Pick<AstEditor, 'addToArray' | 'hasChanges' | 'removeFromArray' | 'setArrayValue' | 'setProperty' | 'overrideTranspileResult'>;

export interface BeforeFileTranspileEvent<TFile extends BscFile = BscFile> {
program: Program;
file: TFile;
outputPath: string;
/**
Expand All @@ -276,6 +277,10 @@ export interface BeforeFileTranspileEvent<TFile extends BscFile = BscFile> {
}

export interface AfterFileTranspileEvent<TFile extends BscFile = BscFile> {
/**
* The program this event was triggered for
*/
program: Program;
file: TFile;
outputPath: string;
/**
Expand Down