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

Refactor Wrapper to Injected Service (WrapperFactory) #536

Merged
merged 24 commits into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ea89232
Break up some dependencies in the expression directory
georg-schwarz Apr 2, 2024
e593726
Inject evaluator and type-computer registry as service
georg-schwarz Apr 2, 2024
15a1213
introduce WrapperFactory for creating BlockTypes and TypedObjects
georg-schwarz Apr 2, 2024
25d030c
Move constraintType wrapping to WrapperFactory
georg-schwarz Apr 2, 2024
27fe35f
Refactor structure of WrapperFactory
georg-schwarz Apr 2, 2024
133d40a
Rename ExpressionEvaluatorRegistry to OperatorEvaluatorRegistry
georg-schwarz Apr 2, 2024
3ebed50
Cleanup ValidationRegistry
georg-schwarz Apr 2, 2024
93e824f
Enforce WrapperFactory over BlocktypeWrapper and ConstraintTypeWrapper
georg-schwarz Apr 2, 2024
620432f
Add license header to new files
georg-schwarz Apr 2, 2024
ecf65ad
Fix docs build
georg-schwarz Apr 2, 2024
70a90a8
Simplify creation of WrapperFactory
georg-schwarz Apr 3, 2024
9abe83b
Add PipelineWrapper functionality to WrapperFactory
georg-schwarz Apr 3, 2024
f7b3c4b
Add PipeWrapper functionality to WrapperFactory
georg-schwarz Apr 3, 2024
85a881d
Add CellRangeWrapper functionality to WrapperFactory
georg-schwarz Apr 3, 2024
0e11e70
Reorganize cell-range util functionality
georg-schwarz Apr 3, 2024
05e21bd
Import WrapperFactory as type
georg-schwarz Apr 3, 2024
73ced3b
Add license infos to new files
georg-schwarz Apr 3, 2024
1dac8ca
Minor fixes to introduced changes (see self-code review)
georg-schwarz Apr 4, 2024
8db76f0
Simplify validation methods by introducing JayveeValidationProps as g…
georg-schwarz Apr 4, 2024
e1e9e01
Move method wrapTypedObject into a dedicated namespace in WrapperFactory
georg-schwarz Apr 4, 2024
c6a069c
Merge branch 'main' into dependency-cycles
georg-schwarz Apr 4, 2024
b167c38
Rename WrapperFactory to WrapperFactoryProvider
georg-schwarz Apr 5, 2024
eb35410
Fix typo in wrappers
georg-schwarz Apr 5, 2024
7f93694
Fix some jsdoc comments
georg-schwarz Apr 5, 2024
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
2 changes: 2 additions & 0 deletions apps/docs/generator/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ function generateBlockTypeDocs(
): void {
const blockTypes = getAllBuiltinBlocktypes(
services.shared.workspace.LangiumDocuments,
services.WrapperFactory,
);

const docsPath = join(
Expand Down Expand Up @@ -72,6 +73,7 @@ function generateConstraintTypeDocs(
);
const constraintTypes = getAllBuiltinConstraintTypes(
services.shared.workspace.LangiumDocuments,
services.WrapperFactory,
);

for (const constraintType of constraintTypes) {
Expand Down
4 changes: 2 additions & 2 deletions libs/execution/src/lib/blocks/block-execution-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
BlockDefinition,
CompositeBlocktypeDefinition,
PipelineDefinition,
PipelineWrapper,
} from '@jvalue/jayvee-language-server';

import { type ExecutionContext } from '../execution-context';
Expand Down Expand Up @@ -34,7 +33,8 @@ export async function executeBlocks(
pipesContainer: CompositeBlocktypeDefinition | PipelineDefinition,
initialInputValue: IOTypeImplementation | undefined = undefined,
): Promise<R.Result<ExecutionOrderItem[]>> {
const pipelineWrapper = new PipelineWrapper(pipesContainer);
const pipelineWrapper =
executionContext.wrapperFactory.Pipeline.wrap(pipesContainer);
const executionOrder: {
block: BlockDefinition;
value: IOTypeImplementation | null;
Expand Down
5 changes: 5 additions & 0 deletions libs/execution/src/lib/blocks/composite-block-executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
IOType,
InternalValueRepresentation,
Valuetype,
WrapperFactory,
createValuetype,
evaluateExpression,
evaluatePropertyValue,
Expand Down Expand Up @@ -133,6 +134,7 @@ export function createCompositeBlockExecutor(
block,
properties,
context.evaluationContext,
context.wrapperFactory,
);

assert(
Expand All @@ -153,6 +155,7 @@ export function createCompositeBlockExecutor(
block: BlockDefinition,
properties: BlocktypeProperty[],
evaluationContext: EvaluationContext,
wrapperFactory: WrapperFactory,
): InternalValueRepresentation | undefined {
const propertyFromBlock = block.body.properties.find(
(property) => property.name === name,
Expand All @@ -162,6 +165,7 @@ export function createCompositeBlockExecutor(
const value = evaluatePropertyValue(
propertyFromBlock,
evaluationContext,
wrapperFactory,
valueType,
);

Expand All @@ -181,6 +185,7 @@ export function createCompositeBlockExecutor(
return evaluateExpression(
propertyFromBlockType.defaultValue,
evaluationContext,
wrapperFactory,
);
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ describe('default constraint extension', () => {

getAllBuiltinConstraintTypes(
services.shared.workspace.LangiumDocuments,
services.WrapperFactory,
).forEach((constraintType) => {
const matchingConstraintExecutorClass = defaultConstraintExtension
.getConstraintExecutors()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ export class ExpressionConstraintExecutor

context.evaluationContext.setValueForValueKeyword(value);

const result = evaluateExpression(expression, context.evaluationContext);
const result = evaluateExpression(
expression,
context.evaluationContext,
context.wrapperFactory,
);
assert(PrimitiveValuetypes.Boolean.isInternalValueRepresentation(result));

context.evaluationContext.deleteValueForValueKeyword();
Expand Down
21 changes: 5 additions & 16 deletions libs/execution/src/lib/execution-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ import { strict as assert } from 'assert';

import {
BlockDefinition,
BlockTypeWrapper,
ConstraintDefinition,
ConstraintTypeWrapper,
EvaluationContext,
InternalValueRepresentation,
PipelineDefinition,
PropertyAssignment,
TransformDefinition,
Valuetype,
type WrapperFactory,
evaluatePropertyValue,
isBlockDefinition,
isExpressionConstraintDefinition,
Expand Down Expand Up @@ -46,6 +45,7 @@ export class ExecutionContext {
public readonly executionExtension: JayveeExecExtension,
public readonly constraintExtension: JayveeConstraintExtension,
public readonly logger: Logger,
public readonly wrapperFactory: WrapperFactory,
public readonly runOptions: {
isDebugMode: boolean;
debugGranularity: DebugGranularity;
Expand Down Expand Up @@ -99,6 +99,7 @@ export class ExecutionContext {
const propertyValue = evaluatePropertyValue(
property,
this.evaluationContext,
this.wrapperFactory,
valuetype,
);
assert(propertyValue !== undefined);
Expand Down Expand Up @@ -152,21 +153,9 @@ export class ExecutionContext {

assert(isReference(currentNode.type));
if (isTypedConstraintDefinition(currentNode)) {
assert(
ConstraintTypeWrapper.canBeWrapped(currentNode.type),
`ConstraintType ${
currentNode.type.ref?.name ?? '<unresolved reference>'
} cannot be wrapped`,
);
return new ConstraintTypeWrapper(currentNode.type);
return this.wrapperFactory.ConstraintType.wrap(currentNode.type);
} else if (isBlockDefinition(currentNode)) {
assert(
BlockTypeWrapper.canBeWrapped(currentNode.type),
`Blocktype ${
currentNode.type.ref?.name ?? '<unresolved reference>'
} cannot be wrapped`,
);
return new BlockTypeWrapper(currentNode.type);
return this.wrapperFactory.BlockType.wrap(currentNode.type);
}
assertUnreachable(currentNode);
}
Expand Down
1 change: 1 addition & 0 deletions libs/execution/src/lib/transforms/transform-executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export class TransformExecutor {
newValue = evaluateExpression(
this.getOutputAssignment().expression,
context.evaluationContext,
context.wrapperFactory,
);
} catch (e) {
if (e instanceof Error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class ValueRepresentationValidityVisitor extends ValuetypeVisitor<boolean> {

const constraints = valuetype.getConstraints(
this.context.evaluationContext,
this.context.wrapperFactory,
);
for (const constraint of constraints) {
const constraintExecutor =
Expand Down
10 changes: 9 additions & 1 deletion libs/execution/test/utils/test-infrastructure-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
// SPDX-License-Identifier: AGPL-3.0-only

import {
DefaultOperatorEvaluatorRegistry,
EvaluationContext,
PipelineDefinition,
RuntimeParameterProvider,
WrapperFactory,
} from '@jvalue/jayvee-language-server';
import { AstNode, AstNodeLocator, LangiumDocument } from 'langium';

Expand Down Expand Up @@ -55,13 +57,19 @@ export function getTestExecutionContext(
'pipelines@0',
) as PipelineDefinition;

const operatorEvaluatorRegistry = new DefaultOperatorEvaluatorRegistry();

const executionContext = new ExecutionContext(
pipeline,
new TestExecExtension(),
new DefaultConstraintExtension(),
new CachedLogger(runOptions.isDebugMode, undefined, loggerPrintLogs),
new WrapperFactory(operatorEvaluatorRegistry),
runOptions,
new EvaluationContext(new RuntimeParameterProvider()),
new EvaluationContext(
new RuntimeParameterProvider(),
operatorEvaluatorRegistry,
),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code snippet exists at a plethora of places. Can we move to a method?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 8db76f0.

);

initialStack.forEach((node) => executionContext.enterNode(node));
Expand Down
36 changes: 27 additions & 9 deletions libs/interpreter-lib/src/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ import {
JayveeModel,
JayveeServices,
PipelineDefinition,
PipelineWrapper,
RuntimeParameterLiteral,
RuntimeParameterProvider,
ValidationContext,
WrapperFactory,
createJayveeServices,
initializeWorkspace,
internalValueToString,
Expand Down Expand Up @@ -136,7 +138,7 @@ export async function interpretModel(
model,
new StdExecExtension(),
new DefaultConstraintExtension(),
services.RuntimeParameterProvider,
services,
loggerFactory,
{
debug: options.debug,
Expand All @@ -158,7 +160,17 @@ function setupJayveeServices(
);

services.validation.ValidationRegistry.registerJayveeValidationChecks({
RuntimeParameterLiteral: validateRuntimeParameterLiteral,
RuntimeParameterLiteral: (
runtimeParameter: RuntimeParameterLiteral,
validationContext: ValidationContext,
evaluationContext: EvaluationContext,
) =>
validateRuntimeParameterLiteral(
runtimeParameter,
validationContext,
evaluationContext,
services.WrapperFactory,
georg-schwarz marked this conversation as resolved.
Show resolved Hide resolved
),
});
}

Expand All @@ -177,7 +189,7 @@ async function interpretJayveeModel(
model: JayveeModel,
executionExtension: JayveeExecExtension,
constraintExtension: JayveeConstraintExtension,
runtimeParameterProvider: RuntimeParameterProvider,
jayveeServices: JayveeServices,
loggerFactory: LoggerFactory,
runOptions: InterpreterOptions,
): Promise<ExitCode> {
Expand All @@ -186,7 +198,7 @@ async function interpretJayveeModel(
pipeline,
executionExtension,
constraintExtension,
runtimeParameterProvider,
jayveeServices,
loggerFactory,
runOptions,
);
Expand All @@ -203,7 +215,7 @@ async function runPipeline(
pipeline: PipelineDefinition,
executionExtension: JayveeExecExtension,
constraintExtension: JayveeConstraintExtension,
runtimeParameterProvider: RuntimeParameterProvider,
jayveeServices: JayveeServices,
loggerFactory: LoggerFactory,
runOptions: InterpreterOptions,
): Promise<ExitCode> {
Expand All @@ -212,18 +224,23 @@ async function runPipeline(
executionExtension,
constraintExtension,
loggerFactory.createLogger(),
jayveeServices.WrapperFactory,
{
isDebugMode: runOptions.debug,
debugGranularity: runOptions.debugGranularity,
debugTargets: runOptions.debugTargets,
},
new EvaluationContext(runtimeParameterProvider),
new EvaluationContext(
jayveeServices.RuntimeParameterProvider,
jayveeServices.operators.EvaluatorRegistry,
),
);

logPipelineOverview(
pipeline,
runtimeParameterProvider,
jayveeServices.RuntimeParameterProvider,
executionContext.logger,
jayveeServices.WrapperFactory,
);

const startTime = new Date();
Expand All @@ -248,8 +265,9 @@ export function logPipelineOverview(
pipeline: PipelineDefinition,
runtimeParameterProvider: RuntimeParameterProvider,
logger: Logger,
wrapperFactory: WrapperFactory,
) {
const pipelineWrapper = new PipelineWrapper(pipeline);
const pipelineWrapper = wrapperFactory.Pipeline.wrap(pipeline);

const toString = (block: BlockDefinition, depth = 0): string => {
const blockTypeName = block.type.ref?.name;
Expand Down
5 changes: 4 additions & 1 deletion libs/interpreter-lib/src/std-extension.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ import { NodeFileSystem } from 'langium/node';
async function loadAllBuiltinBlocktypes(): Promise<BlockTypeWrapper[]> {
const services = createJayveeServices(NodeFileSystem).Jayvee;
await initializeWorkspace(services);
return getAllBuiltinBlocktypes(services.shared.workspace.LangiumDocuments);
return getAllBuiltinBlocktypes(
services.shared.workspace.LangiumDocuments,
services.WrapperFactory,
);
}

describe('std extension', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import * as path from 'path';

import { parseValueToInternalRepresentation } from '@jvalue/jayvee-execution';
import {
DefaultOperatorEvaluatorRegistry,
DefaultOperatorTypeComputerRegistry,
EvaluationContext,
RuntimeParameterLiteral,
RuntimeParameterProvider,
ValidationContext,
WrapperFactory,
createJayveeServices,
} from '@jvalue/jayvee-language-server';
import {
Expand Down Expand Up @@ -60,10 +63,19 @@ describe('Validation of validateRuntimeParameterLiteral', () => {
}
}

const operatorEvaluatorRegistry = new DefaultOperatorEvaluatorRegistry();
const operatorTypeComputerRegistry =
new DefaultOperatorTypeComputerRegistry();
const wrapperFactory = new WrapperFactory(operatorEvaluatorRegistry);

validateRuntimeParameterLiteral(
runtimeParameter,
new ValidationContext(validationAcceptorMock),
new EvaluationContext(runtimeProvider),
new ValidationContext(
validationAcceptorMock,
operatorTypeComputerRegistry,
),
new EvaluationContext(runtimeProvider, operatorEvaluatorRegistry),
wrapperFactory,
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ import {
ReferenceableBlocktypeDefinition,
RuntimeParameterLiteral,
ValidationContext,
getTypedObjectWrapper,
type WrapperFactory,
} from '@jvalue/jayvee-language-server';
import { Reference } from 'langium';

export function validateRuntimeParameterLiteral(
runtimeParameter: RuntimeParameterLiteral,
validationContext: ValidationContext,
evaluationContext: EvaluationContext,
wrapperFactory: WrapperFactory,
) {
checkRuntimeParameterValuePresence(
runtimeParameter,
Expand All @@ -31,6 +32,7 @@ export function validateRuntimeParameterLiteral(
runtimeParameter,
validationContext,
evaluationContext,
wrapperFactory,
);
}

Expand Down Expand Up @@ -59,6 +61,7 @@ function checkRuntimeParameterValueParsing(
runtimeParameter: RuntimeParameterLiteral,
validationContext: ValidationContext,
evaluationContext: EvaluationContext,
wrapperFactory: WrapperFactory,
) {
const enclosingPropertyBody = getEnclosingPropertyBody(runtimeParameter);
const type:
Expand All @@ -67,7 +70,7 @@ function checkRuntimeParameterValueParsing(
| undefined =
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
enclosingPropertyBody.$container?.type;
const wrapper = getTypedObjectWrapper(type);
const wrapper = wrapperFactory.wrapTypedObject(type);

// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
const propertyName = runtimeParameter.$container?.name;
Expand Down
Loading
Loading