Skip to content
Merged
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
65 changes: 44 additions & 21 deletions src/blocks/mrc_call_python_function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,13 @@ import { MRC_STYLE_FUNCTIONS } from '../themes/styles'

export const BLOCK_NAME = 'mrc_call_python_function';

const FUNCTION_KIND_MODULE = 'module';
const FUNCTION_KIND_STATIC = 'static';
const FUNCTION_KIND_CONSTRUCTOR = 'constructor';
const FUNCTION_KIND_INSTANCE = 'instance';
enum FunctionKind {
MODULE = 'module',
STATIC = 'static',
CONSTRUCTOR = 'constructor',
INSTANCE = 'instance',
INSTANCE_WITHIN = 'instance_within',
}

const RETURN_TYPE_NONE = 'None';

Expand All @@ -47,7 +50,7 @@ export type FunctionArg = {

type CallPythonFunctionBlock = Blockly.Block & CallPythonFunctionMixin;
interface CallPythonFunctionMixin extends CallPythonFunctionMixinType {
mrcFunctionKind: string, // module, static, constructor, or instance
mrcFunctionKind: FunctionKind,
mrcReturnType: string,
mrcArgs: FunctionArg[],
mrcTooltip: string,
Expand All @@ -60,7 +63,7 @@ type CallPythonFunctionMixinType = typeof CALL_PYTHON_FUNCTION;
/** Extra state for serialising call_python_* blocks. */
type CallPythonFunctionExtraState = {
/**
* The kind of function: module, static, constructor, or instance.
* The kind of function. Must be one of the FunctionKind enum values as a string.
*/
functionKind: string,
/**
Expand Down Expand Up @@ -104,31 +107,36 @@ const CALL_PYTHON_FUNCTION = {
this.setTooltip(() => {
let tooltip: string;
switch (this.mrcFunctionKind) {
case FUNCTION_KIND_MODULE: {
case FunctionKind.MODULE: {
const moduleName = this.getFieldValue(pythonUtils.FIELD_MODULE_OR_CLASS_NAME);
const functionName = this.getFieldValue(pythonUtils.FIELD_FUNCTION_NAME);
tooltip = 'Calls the function ' + moduleName + '.' + functionName + '.';
break;
}
case FUNCTION_KIND_STATIC: {
case FunctionKind.STATIC: {
const className = this.getFieldValue(pythonUtils.FIELD_MODULE_OR_CLASS_NAME);
const functionName = this.getFieldValue(pythonUtils.FIELD_FUNCTION_NAME);
tooltip = 'Calls the function ' + className + '.' + functionName + '.';
break;
}
case FUNCTION_KIND_CONSTRUCTOR: {
case FunctionKind.CONSTRUCTOR: {
const className = this.getFieldValue(pythonUtils.FIELD_MODULE_OR_CLASS_NAME);
tooltip = 'Constructs an instance of the class ' + className + '.';
break;
}
case FUNCTION_KIND_INSTANCE: {
case FunctionKind.INSTANCE: {
const className = this.getFieldValue(pythonUtils.FIELD_MODULE_OR_CLASS_NAME);
const functionName = this.getFieldValue(pythonUtils.FIELD_FUNCTION_NAME);
tooltip = 'Calls the function ' + className + '.' + functionName + '.';
break;
}
case FunctionKind.INSTANCE_WITHIN: {
const functionName = this.getFieldValue(pythonUtils.FIELD_FUNCTION_NAME);
tooltip = 'Calls the method ' + functionName + '.';
break;
}
default:
throw new Error('mrcVarKind must be "module", "static", "constructor", or "instance".')
throw new Error('mrcFunctionKind has unexpected value: ' + mrcFunctionKind)
}
const funcTooltip = this.mrcTooltip;
if (funcTooltip) {
Expand Down Expand Up @@ -172,7 +180,7 @@ const CALL_PYTHON_FUNCTION = {
this: CallPythonFunctionBlock,
extraState: CallPythonFunctionExtraState
): void {
this.mrcFunctionKind = extraState.functionKind;
this.mrcFunctionKind = extraState.functionKind as FunctionKind;
this.mrcReturnType = extraState.returnType;
this.mrcArgs = [];
extraState.args.forEach((arg) => {
Expand Down Expand Up @@ -212,34 +220,39 @@ const CALL_PYTHON_FUNCTION = {
}
// Add the dummy input.
switch (this.mrcFunctionKind) {
case FUNCTION_KIND_MODULE:
case FunctionKind.MODULE:
this.appendDummyInput()
.appendField('call')
.appendField(createFieldNonEditableText(''), pythonUtils.FIELD_MODULE_OR_CLASS_NAME)
.appendField('.')
.appendField(createFieldNonEditableText(''), pythonUtils.FIELD_FUNCTION_NAME);
break;
case FUNCTION_KIND_STATIC:
case FunctionKind.STATIC:
this.appendDummyInput()
.appendField('call')
.appendField(createFieldNonEditableText(''), pythonUtils.FIELD_MODULE_OR_CLASS_NAME)
.appendField('.')
.appendField(createFieldNonEditableText(''), pythonUtils.FIELD_FUNCTION_NAME);
break;
case FUNCTION_KIND_CONSTRUCTOR:
case FunctionKind.CONSTRUCTOR:
this.appendDummyInput()
.appendField('create')
.appendField(createFieldNonEditableText(''), pythonUtils.FIELD_MODULE_OR_CLASS_NAME);
break;
case FUNCTION_KIND_INSTANCE:
case FunctionKind.INSTANCE:
this.appendDummyInput()
.appendField('call')
.appendField(createFieldNonEditableText(''), pythonUtils.FIELD_MODULE_OR_CLASS_NAME)
.appendField('.')
.appendField(createFieldNonEditableText(''), pythonUtils.FIELD_FUNCTION_NAME);
break;
case FunctionKind.INSTANCE_WITHIN:
this.appendDummyInput()
.appendField('call')
.appendField(createFieldNonEditableText(''), pythonUtils.FIELD_FUNCTION_NAME);
break;
default:
throw new Error('mrcVarKind must be "module", "static", "constructor", or "instance".')
throw new Error('mrcFunctionKind has unexpected value: ' + mrcFunctionKind)
}
// Add input sockets for the arguments.
for (let i = 0; i < this.mrcArgs.length; i++) {
Expand Down Expand Up @@ -268,15 +281,15 @@ export const pythonFromBlock = function(
let code;
let argStartIndex = 0;
switch (callPythonFunctionBlock.mrcFunctionKind) {
case FUNCTION_KIND_MODULE: {
case FunctionKind.MODULE: {
const moduleName = block.getFieldValue(pythonUtils.FIELD_MODULE_OR_CLASS_NAME);
const functionName = (callPythonFunctionBlock.mrcActualFunctionName)
? callPythonFunctionBlock.mrcActualFunctionName
: block.getFieldValue(pythonUtils.FIELD_FUNCTION_NAME);
code = moduleName + '.' + functionName;
break;
}
case FUNCTION_KIND_STATIC: {
case FunctionKind.STATIC: {
const callPythonFunctionBlock = block as CallPythonFunctionBlock;
const className = block.getFieldValue(pythonUtils.FIELD_MODULE_OR_CLASS_NAME);
const functionName = (callPythonFunctionBlock.mrcActualFunctionName)
Expand All @@ -285,13 +298,13 @@ export const pythonFromBlock = function(
code = className + '.' + functionName;
break;
}
case FUNCTION_KIND_CONSTRUCTOR: {
case FunctionKind.CONSTRUCTOR: {
const callPythonFunctionBlock = block as CallPythonFunctionBlock;
const className = block.getFieldValue(pythonUtils.FIELD_MODULE_OR_CLASS_NAME);
code = className;
break;
}
case FUNCTION_KIND_INSTANCE: {
case FunctionKind.INSTANCE: {
const callPythonFunctionBlock = block as CallPythonFunctionBlock;
const selfValue = generator.valueToCode(block, 'ARG0', Order.MEMBER);
const functionName = (callPythonFunctionBlock.mrcActualFunctionName)
Expand All @@ -301,6 +314,16 @@ export const pythonFromBlock = function(
argStartIndex = 1; // Skip the self argument.
break;
}
case FunctionKind.INSTANCE_WITHIN: {
const callPythonFunctionBlock = block as CallPythonFunctionBlock;
const functionName = (callPythonFunctionBlock.mrcActualFunctionName)
? callPythonFunctionBlock.mrcActualFunctionName
: block.getFieldValue(pythonUtils.FIELD_FUNCTION_NAME);
code = 'self.' + functionName;
break;
}
default:
throw new Error('mrcFunctionKind has unexpected value: ' + mrcFunctionKind)
}
code += '(' + generateCodeForArguments(callPythonFunctionBlock, generator, argStartIndex) + ')';
if (block.outputConnection) {
Expand Down