Skip to content

Commit 6efebe4

Browse files
committed
In mrc_class_method_def.ts:
Added constants for NO_RETURN_VALUE and UNTYPED_RETURN_VALUE. Added upgrade_004_to_005 to change mrcReturnType from 'Any' to UNTYPED_RETURN_VALUE. Changed createCustomMethodBlockWithReturn to use UNTYPED_RETURN_VALUE instead of 'Any'. In upgrade_project.ts: Incremented CURRENT_VERSION to 0.0.5. Changed switch statement in upgradeProjectIfNecessary to have the default case at the top. All other cases have @ts-ignore and blank lines so it is more clear that the @ts-ignore goes with the case after it. Added upgradeBlocksFiles function that can be called from other upgradeFrom_..._to_... functions. Added upgradeFrom_004_to_005.
1 parent 2523d8a commit 6efebe4

File tree

2 files changed

+89
-14
lines changed

2 files changed

+89
-14
lines changed

src/blocks/mrc_class_method_def.ts

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ import * as paramContainer from './mrc_param_container'
3737

3838
export const BLOCK_NAME = 'mrc_class_method_def';
3939

40+
const NO_RETURN_VALUE = 'None';
41+
const UNTYPED_RETURN_VALUE = '';
42+
4043
const INPUT_TITLE = 'TITLE';
4144
export const FIELD_METHOD_NAME = 'NAME';
4245
const FIELD_PARAM_PREFIX = 'PARAM_';
@@ -82,8 +85,8 @@ type ClassMethodDefExtraState = {
8285
canBeCalledOutsideClass: boolean,
8386
/**
8487
* The return type of the function.
85-
* Use 'None' for no return value.
86-
* Use '' for an untyped return value.
88+
* Use NO_RETURN_VALUE for no return value.
89+
* Use UNTYPED_RETURN_VALUE for an untyped return value.
8790
*/
8891
returnType: string,
8992
/**
@@ -252,8 +255,8 @@ const CLASS_METHOD_DEF = {
252255
this.removeInput(INPUT_RETURN);
253256
}
254257

255-
// Add return input if return type is not 'None'
256-
if (this.mrcReturnType && this.mrcReturnType !== 'None') {
258+
// Add return input if return type is not NO_RETURN_VALUE
259+
if (this.mrcReturnType !== undefined && this.mrcReturnType !== NO_RETURN_VALUE) {
257260
this.appendValueInput(INPUT_RETURN)
258261
.setAlign(Blockly.inputs.Align.RIGHT)
259262
.appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
@@ -348,6 +351,11 @@ const CLASS_METHOD_DEF = {
348351
methodBlock.mrcParameters = filteredParams;
349352
}
350353
},
354+
upgrade_004_to_005: function(this: ClassMethodDefBlock) {
355+
if (this.mrcReturnType === 'Any') {
356+
this.mrcReturnType = UNTYPED_RETURN_VALUE;
357+
}
358+
},
351359
};
352360

353361
/**
@@ -508,7 +516,7 @@ export function createCustomMethodBlock(): toolboxItems.Block {
508516
canChangeSignature: true,
509517
canBeCalledWithinClass: true,
510518
canBeCalledOutsideClass: true,
511-
returnType: 'None',
519+
returnType: NO_RETURN_VALUE,
512520
params: [],
513521
};
514522
const fields: {[key: string]: any} = {};
@@ -521,7 +529,7 @@ export function createCustomMethodBlockWithReturn(): toolboxItems.Block {
521529
canChangeSignature: true,
522530
canBeCalledWithinClass: true,
523531
canBeCalledOutsideClass: true,
524-
returnType: 'Any',
532+
returnType: UNTYPED_RETURN_VALUE,
525533
params: [],
526534
};
527535
const fields: {[key: string]: any} = {};
@@ -609,3 +617,17 @@ export function getMethodNamesAlreadyOverriddenInWorkspace(
609617
}
610618
});
611619
}
620+
621+
/**
622+
* Upgrades the ClassMethodDefBlocks in the given workspace from version 004 to 005.
623+
* This function should only be called when upgrading old projects.
624+
*/
625+
export function upgrade_004_to_005(workspace: Blockly.Workspace): void {
626+
// Make sure the workspace is headless.
627+
if (workspace.rendered) {
628+
throw new Error('upgrade_004_to_005 should never be called with a rendered workspace.');
629+
}
630+
workspace.getBlocksByType(BLOCK_NAME).forEach(block => {
631+
(block as ClassMethodDefBlock).upgrade_004_to_005();
632+
});
633+
}

src/storage/upgrade_project.ts

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,39 +28,83 @@ import * as storageModule from './module';
2828
import * as storageModuleContent from './module_content';
2929
import * as storageNames from './names';
3030
import * as storageProject from './project';
31-
import { ClassMethodDefBlock, BLOCK_NAME as MRC_CLASS_METHOD_DEF_BLOCK_NAME } from '../blocks/mrc_class_method_def';
31+
import { ClassMethodDefBlock, BLOCK_NAME as MRC_CLASS_METHOD_DEF_BLOCK_NAME, upgrade_004_to_005 } from '../blocks/mrc_class_method_def';
3232
import * as workspaces from '../blocks/utils/workspaces';
3333

3434
export const NO_VERSION = '0.0.0';
35-
export const CURRENT_VERSION = '0.0.4';
35+
export const CURRENT_VERSION = '0.0.5';
3636

3737
export async function upgradeProjectIfNecessary(
3838
storage: commonStorage.Storage, projectName: string): Promise<void> {
3939
const projectInfo = await storageProject.fetchProjectInfo(storage, projectName);
4040
if (semver.lt(projectInfo.version, CURRENT_VERSION)) {
4141
switch (projectInfo.version) {
42+
default:
43+
throw new Error('Unrecognized project version: ' + projectInfo.version);
44+
45+
// Intentional fallthrough after case '0.0.0'
4246
// @ts-ignore
4347
case '0.0.0':
4448
upgradeFrom_000_to_001(storage, projectName, projectInfo)
45-
// Intentional fallthrough
49+
50+
// Intentional fallthrough after case '0.0.1'
4651
// @ts-ignore
4752
case '0.0.1':
4853
upgradeFrom_001_to_002(storage, projectName, projectInfo);
49-
// Intentional fallthrough
54+
55+
// Intentional fallthrough after case '0.0.2'
5056
// @ts-ignore
5157
case '0.0.2':
52-
upgradeFrom_002_to_003(storage, projectName, projectInfo);
58+
upgradeFrom_002_to_003(storage, projectName, projectInfo);
59+
60+
// Intentional fallthrough after case '0.0.3'
61+
// @ts-ignore
5362
case '0.0.3':
5463
upgradeFrom_003_to_004(storage, projectName, projectInfo);
55-
break;
56-
default:
57-
throw new Error('Unrecognized project version: ' + projectInfo.version);
5864

65+
// Intentional fallthrough after case '0.0.4'
66+
// @ts-ignore
67+
case '0.0.4':
68+
upgradeFrom_004_to_005(storage, projectName, projectInfo);
5969
}
6070
await storageProject.saveProjectInfo(storage, projectName);
6171
}
6272
}
6373

74+
async function upgradeBlocksFiles(
75+
storage: commonStorage.Storage,
76+
projectName: string,
77+
upgradeFunc: (w: Blockly.Workspace) => void
78+
): Promise<void> {
79+
const projectFileNames: string[] = await storage.list(
80+
storageNames.makeProjectDirectoryPath(projectName));
81+
for (const projectFileName of projectFileNames) {
82+
const modulePath = storageNames.makeFilePath(projectName, projectFileName);
83+
const moduleType = storageNames.getModuleType(modulePath);
84+
85+
let moduleContentText = await storage.fetchFileContentText(modulePath);
86+
const moduleContent = storageModuleContent.parseModuleContentText(moduleContentText);
87+
let blocks = moduleContent.getBlocks();
88+
89+
// Create a temporary workspace to upgrade the blocks.
90+
const headlessWorkspace = workspaces.createHeadlessWorkspace(moduleType);
91+
92+
try {
93+
Blockly.serialization.workspaces.load(blocks, headlessWorkspace);
94+
95+
upgradeFunc(headlessWorkspace);
96+
97+
blocks = Blockly.serialization.workspaces.save(headlessWorkspace);
98+
} finally {
99+
workspaces.destroyHeadlessWorkspace(headlessWorkspace);
100+
}
101+
102+
moduleContent.setBlocks(blocks);
103+
moduleContentText = moduleContent.getModuleContentText();
104+
await storage.saveFile(modulePath, moduleContentText);
105+
}
106+
}
107+
64108
async function upgradeFrom_000_to_001(
65109
_storage: commonStorage.Storage,
66110
_projectName: string,
@@ -157,3 +201,12 @@ async function upgradeFrom_003_to_004(
157201
// from loading a project with an older version of software.
158202
projectInfo.version = '0.0.4';
159203
}
204+
205+
async function upgradeFrom_004_to_005(
206+
storage: commonStorage.Storage,
207+
projectName: string,
208+
projectInfo: storageProject.ProjectInfo): Promise<void> {
209+
// mrc_class_method_def blocks that return a value need to have returnType changed from 'Any' to ''.
210+
await upgradeBlocksFiles(storage, projectName, upgrade_004_to_005);
211+
projectInfo.version = '0.0.5';
212+
}

0 commit comments

Comments
 (0)