Skip to content

Commit

Permalink
Applied review feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
rhazn committed Aug 30, 2023
1 parent 5c50a1d commit 9fba159
Show file tree
Hide file tree
Showing 11 changed files with 44 additions and 41 deletions.
22 changes: 15 additions & 7 deletions libs/execution/src/lib/blocks/block-execution-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,21 @@ export interface ExecutionOrderItem {
value: IOTypeImplementation | null;
}

/**
* Executes an ordered list of blocks in sequence, using outputs from previous blocks as inputs for downstream blocks.
*
* @param executionContext The context the blocks are executed in, e.g., a pipeline or composite block
* @param executionOrder An ordered list of blocks so that blocks that need inputs are after blocks that produce these inputs
* @param initialInputValue An initial input that was produced outside of this block chain, e.g., as input to a composite block
*
* @returns The ordered blocks and their produced outputs or an error on failure
*/
export async function executeBlocks(
executionContext: ExecutionContext,
executionOrder: ExecutionOrderItem[],
initialInputValue: IOTypeImplementation | undefined = undefined,
): Promise<R.Result<ExecutionOrderItem[]>> {
let isFirstblock = true;
let isFirstBlock = true;

for (const blockData of executionOrder) {
const block = blockData.block;
Expand All @@ -35,11 +44,10 @@ export async function executeBlocks(
let inputValue =
parentData[0]?.value === undefined ? NONE : parentData[0]?.value;

if (
isFirstblock &&
inputValue === NONE &&
initialInputValue !== undefined
) {
const useExternalInputValueForFirstBlock =
isFirstBlock && inputValue === NONE && initialInputValue !== undefined;

if (useExternalInputValueForFirstBlock) {
inputValue = initialInputValue;
}

Expand All @@ -57,7 +65,7 @@ export async function executeBlocks(
blockData.value = blockResultData;

executionContext.exitNode(block);
isFirstblock = false;
isFirstBlock = false;
}
return R.ok(executionOrder);
}
Expand Down
9 changes: 4 additions & 5 deletions libs/execution/src/lib/blocks/block-executor-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,11 @@ export function getRegisteredBlockExecutors(): BlockExecutorClass[] {
}

export function createBlockExecutor(block: BlockDefinition): BlockExecutor {
const blockType = block.type.ref?.name;
const blockType = block.type.ref;
assert(blockType !== undefined);

if (
!blockExecutorRegistry.get(blockType) &&
block.type.ref &&
!blockExecutorRegistry.get(blockType.name) &&
isCompositeBlocktypeDefinition(block.type.ref)
) {
const executorClass = createCompositeBlockExecutor(
Expand All @@ -47,11 +46,11 @@ export function createBlockExecutor(block: BlockDefinition): BlockExecutor {
blockExecutorRegistry.register(block.type.ref.name, executorClass);
}

const blockExecutor = blockExecutorRegistry.get(blockType);
const blockExecutor = blockExecutorRegistry.get(blockType.name);

assert(
blockExecutor !== undefined,
`No executor was registered for block type ${blockType}`,
`No executor was registered for block type ${blockType.name}`,
);

return new blockExecutor();
Expand Down
12 changes: 4 additions & 8 deletions libs/execution/src/lib/blocks/composite-block-executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,9 @@ export function createCompositeBlockExecutor(

this.removeVariablesFromContext(blockTypeReference.properties, context);

const pipeline = getPipeline(blockTypeReference);

if (R.isOk(executionResult)) {
// The last block always pipes into the output if it exists
const pipeline = getPipeline(blockTypeReference);
const lastBlock = pipeline.blocks.at(-1);

const blockExecutionResult = R.okData(executionResult).find(
Expand Down Expand Up @@ -129,7 +128,7 @@ export function createCompositeBlockExecutor(
context: ExecutionContext,
) {
properties.forEach((blocktypeProperty) => {
const valueType = createValuetype(blocktypeProperty.valuetype);
const valueType = createValuetype(blocktypeProperty.valueType);

assert(
valueType,
Expand Down Expand Up @@ -167,7 +166,7 @@ export function createCompositeBlockExecutor(
(property) => property.name === name,
);

if (propertyFromBlock) {
if (propertyFromBlock !== undefined) {
const value = evaluatePropertyValue(
propertyFromBlock,
evaluationContext,
Expand All @@ -183,10 +182,7 @@ export function createCompositeBlockExecutor(
(property) => property.name === name,
);

if (
!propertyFromBlockType ||
propertyFromBlockType.defaultValue === undefined
) {
if (propertyFromBlockType?.defaultValue === undefined) {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion libs/language-server/src/grammar/blocktype.langium
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ BlocktypeOutput:
'output' name=ID 'oftype' iotype=[IotypeDefinition] ';';

BlocktypeProperty:
'property' name=ID 'oftype' valuetype=ValuetypeReference (':' defaultValue=Expression)? ';';
'property' name=ID 'oftype' valueType=ValuetypeReference (':' defaultValue=Expression)? ';';

BlocktypePipeline:
input=[BlocktypeInput] '->' (blocks+=[BlockDefinition] '->')+ output=[BlocktypeOutput] ';';
Original file line number Diff line number Diff line change
Expand Up @@ -331,9 +331,7 @@ function inferTypeFromReferenceLiteral(
isTransformPortDefinition(referenced) ||
isBlocktypeProperty(referenced)
) {
const valueType = isTransformPortDefinition(referenced)
? referenced.valueType
: referenced.valuetype;
const valueType = referenced.valueType;
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (valueType === undefined) {
return undefined;
Expand Down
12 changes: 8 additions & 4 deletions libs/language-server/src/lib/ast/io-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@ export enum IOType {
}

export function getIOType(blockIO: BlocktypeInput | BlocktypeOutput): IOType {
const ioName = blockIO.iotype.ref?.name as string;
const ioTypeName = blockIO.iotype.ref?.name;
assert(
ioTypeName !== undefined,
`Unknown IOType name for block input/output ${blockIO.name}.`,
);

assert(
Object.values(IOType).some((type) => type === ioName),
`IOType ${ioName} does not exist.`,
Object.values(IOType).some((type) => type === ioTypeName),
`IOType ${ioTypeName} does not exist.`,
);

return ioName as IOType;
return ioTypeName as IOType;
}
5 changes: 2 additions & 3 deletions libs/language-server/src/lib/ast/model-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,14 @@ export function collectStartingBlocks(
.map((pipe) => pipe.blocks[0])
.map((blockRef: Reference<BlockDefinition> | undefined) => {
if (
blockRef &&
blockRef.ref &&
blockRef?.ref !== undefined &&
getMetaInformation(blockRef.ref.type) !== undefined
) {
return blockRef.ref;
}
return undefined;
})
.filter(Boolean) as unknown as BlockDefinition[];
.filter((x): x is BlockDefinition => x !== undefined);

return startingBlocks;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class CompositeBlocktypeMetaInformation extends BlockMetaInformation {
const properties: Record<string, PropertySpecification> = {};

for (const property of blockTypeDefinition.properties) {
const valuetype = createValuetype(property.valuetype);
const valuetype = createValuetype(property.valueType);
assert(valuetype !== undefined);

properties[property.name] = {
Expand Down Expand Up @@ -50,7 +50,7 @@ export class CompositeBlocktypeMetaInformation extends BlockMetaInformation {
(blocktypeProperty) => blocktypeProperty.name === propertyName,
);

return !blocktypeProperty?.defaultValue;
return blocktypeProperty?.defaultValue === undefined;
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,12 @@ function checkPipesOfBlock(
);
}
} else if (pipes.length === 0) {
const isLastBlockOfCompositeBlocktype =
isCompositeBlocktypeDefinition(block.$container) &&
block.$container.blocks.at(-1)?.name === block.name;

// The last block in a composite block is connected to the output, not another block
if (
!(
isCompositeBlocktypeDefinition(block.$container) &&
block.$container.blocks.at(-1)?.name === block.name
)
) {
if (!isLastBlockOfCompositeBlocktype) {
context.accept(
'warning',
`A pipe should be connected to the ${whatToCheck} of this block`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ function checkPropertyDefaultValuesHasCorrectType(
}

// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
const expectedValuetype = createValuetype(property.valuetype?.reference?.ref);
const expectedValuetype = createValuetype(property.valueType?.reference?.ref);
assert(expectedValuetype !== undefined);

if (!expectedValuetype.isInternalValueRepresentation(evaluatedExpression)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ describe('Validation of ValuetypeReference', () => {
expectNoParserAndLexerErrors(document);
const valuetypeRef = locator.getAstNode<ValuetypeReference>(
document.parseResult.value,
`blocktypes@0/properties@0/valuetype`,
`blocktypes@0/properties@0/valueType`,
);
assert(valuetypeRef !== undefined);

Expand Down

0 comments on commit 9fba159

Please sign in to comment.