Refactor to improve iterations
- Use function abstractions (such as map, reduce, filter etc.) over for-of loops to gain benefits of having less side effects and easier readability. - Enable `downLevelIterations` for writing modern code with lazy evaluation. - Refactor for of loops to named abstractions to clearly express their intentions without needing to analyse the loop itself. - Add missing cases for changes that had no tests.
This commit is contained in:
@@ -42,13 +42,12 @@ export class CodeChangedEvent implements ICodeChangedEvent {
|
||||
|
||||
function ensureAllPositionsExist(script: string, positions: ReadonlyArray<ICodePosition>) {
|
||||
const totalLines = script.split(/\r\n|\r|\n/).length;
|
||||
for (const position of positions) {
|
||||
if (position.endLine > totalLines) {
|
||||
throw new Error(
|
||||
`script end line (${position.endLine}) is out of range.`
|
||||
+ `(total code lines: ${totalLines}`,
|
||||
);
|
||||
}
|
||||
const missingPositions = positions.filter((position) => position.endLine > totalLines);
|
||||
if (missingPositions.length > 0) {
|
||||
throw new Error(
|
||||
`Out of range script end line: "${missingPositions.map((pos) => pos.endLine).join('", "')}"`
|
||||
+ `(total code lines: ${totalLines}).`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,7 @@ export abstract class CodeBuilder implements ICodeBuilder {
|
||||
return this;
|
||||
}
|
||||
const lines = code.match(/[^\r\n]+/g);
|
||||
for (const line of lines) {
|
||||
this.lines.push(line);
|
||||
}
|
||||
this.lines.push(...lines);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,15 +19,14 @@ export class UserScriptGenerator implements IUserScriptGenerator {
|
||||
): IUserScript {
|
||||
if (!selectedScripts) { throw new Error('undefined scripts'); }
|
||||
if (!scriptingDefinition) { throw new Error('undefined definition'); }
|
||||
let scriptPositions = new Map<SelectedScript, ICodePosition>();
|
||||
if (!selectedScripts.length) {
|
||||
return { code: '', scriptPositions };
|
||||
return { code: '', scriptPositions: new Map<SelectedScript, ICodePosition>() };
|
||||
}
|
||||
let builder = this.codeBuilderFactory.create(scriptingDefinition.language);
|
||||
builder = initializeCode(scriptingDefinition.startCode, builder);
|
||||
for (const selection of selectedScripts) {
|
||||
scriptPositions = appendSelection(selection, scriptPositions, builder);
|
||||
}
|
||||
const scriptPositions = selectedScripts.reduce((result, selection) => {
|
||||
return appendSelection(selection, result, builder);
|
||||
}, new Map<SelectedScript, ICodePosition>());
|
||||
const code = finalizeCode(builder, scriptingDefinition.endCode);
|
||||
return { code, scriptPositions };
|
||||
}
|
||||
|
||||
@@ -17,10 +17,8 @@ export class UserSelection implements IUserSelection {
|
||||
selectedScripts: ReadonlyArray<SelectedScript>,
|
||||
) {
|
||||
this.scripts = new InMemoryRepository<string, SelectedScript>();
|
||||
if (selectedScripts && selectedScripts.length > 0) {
|
||||
for (const script of selectedScripts) {
|
||||
this.scripts.addItem(script);
|
||||
}
|
||||
for (const script of selectedScripts) {
|
||||
this.scripts.addItem(script);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,18 +56,19 @@ export class UserSelection implements IUserSelection {
|
||||
}
|
||||
|
||||
public addOrUpdateAllInCategory(categoryId: number, revert = false): void {
|
||||
const category = this.collection.findCategory(categoryId);
|
||||
const scriptsToAddOrUpdate = category.getAllScriptsRecursively()
|
||||
const scriptsToAddOrUpdate = this.collection
|
||||
.findCategory(categoryId)
|
||||
.getAllScriptsRecursively()
|
||||
.filter(
|
||||
(script) => !this.scripts.exists(script.id)
|
||||
|| this.scripts.getById(script.id).revert !== revert,
|
||||
);
|
||||
)
|
||||
.map((script) => new SelectedScript(script, revert));
|
||||
if (!scriptsToAddOrUpdate.length) {
|
||||
return;
|
||||
}
|
||||
for (const script of scriptsToAddOrUpdate) {
|
||||
const selectedScript = new SelectedScript(script, revert);
|
||||
this.scripts.addOrUpdateItem(selectedScript);
|
||||
this.scripts.addOrUpdateItem(script);
|
||||
}
|
||||
this.changed.notify(this.scripts.getItems());
|
||||
}
|
||||
@@ -106,11 +105,12 @@ export class UserSelection implements IUserSelection {
|
||||
}
|
||||
|
||||
public selectAll(): void {
|
||||
for (const script of this.collection.getAllScripts()) {
|
||||
if (!this.scripts.exists(script.id)) {
|
||||
const selection = new SelectedScript(script, false);
|
||||
this.scripts.addItem(selection);
|
||||
}
|
||||
const scriptsToSelect = this.collection
|
||||
.getAllScripts()
|
||||
.filter((script) => !this.scripts.exists(script.id))
|
||||
.map((script) => new SelectedScript(script, false));
|
||||
for (const script of scriptsToSelect) {
|
||||
this.scripts.addItem(script);
|
||||
}
|
||||
this.changed.notify(this.scripts.getItems());
|
||||
}
|
||||
@@ -135,10 +135,11 @@ export class UserSelection implements IUserSelection {
|
||||
.forEach((scriptId) => this.scripts.removeItem(scriptId));
|
||||
}
|
||||
// Select from unselected scripts
|
||||
const unselectedScripts = scripts.filter((script) => !this.scripts.exists(script.id));
|
||||
const unselectedScripts = scripts
|
||||
.filter((script) => !this.scripts.exists(script.id))
|
||||
.map((script) => new SelectedScript(script, false));
|
||||
for (const toSelect of unselectedScripts) {
|
||||
const selection = new SelectedScript(toSelect, false);
|
||||
this.scripts.addItem(selection);
|
||||
this.scripts.addItem(toSelect);
|
||||
}
|
||||
this.changed.notify(this.scripts.getItems());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user