Skip to content

Commit

Permalink
refactor: . Move constructArguments() & parseAndEvaluateExpression() …
Browse files Browse the repository at this point in the history
…to TaskExpression.ts
  • Loading branch information
claremacrae committed Oct 28, 2023
1 parent 75e8903 commit c72cdcd
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 55 deletions.
3 changes: 1 addition & 2 deletions src/Query/Filter/FunctionField.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { parseAndEvaluateExpression } from '../../Scripting/Expression';
import type { Task } from '../../Task';
import type { GrouperFunction } from '../Grouper';
import { Grouper } from '../Grouper';
import { Explanation } from '../Explain/Explanation';
import { TaskExpression } from '../../Scripting/TaskExpression';
import { TaskExpression, parseAndEvaluateExpression } from '../../Scripting/TaskExpression';
import { Field } from './Field';
import { Filter, type FilterFunction } from './Filter';
import { FilterOrErrorMessage } from './FilterOrErrorMessage';
Expand Down
38 changes: 0 additions & 38 deletions src/Scripting/Expression.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,8 @@
import type { Task } from '../Task';
import { QueryComponentOrError } from '../Query/QueryComponentOrError';
import { errorMessageForException } from '../lib/ExceptionTools';

export class FunctionOrError extends QueryComponentOrError<Function> {}

/**
* From: https://www.educative.io/answers/parameter-vs-argument
* A parameter is a variable in a function definition. It is a placeholder and hence does not have a concrete value.
* An argument is a value passed during function invocation.
* @param task - during parsing, this can be null. During evaluation, it must be a Task
*/
export function constructArguments(task: Task | null) {
// TODO Move this to TaskExpression
const paramsArgs: [string, any][] = [
// TODO Later, pass in the Query too, for access to file properties
['task', task],
];
return paramsArgs;
}

/**
* Parse a JavaScript expression, and return either a Function or an error message in a string.
* @param paramsArgs
Expand Down Expand Up @@ -71,25 +55,3 @@ export function evaluateExpressionOrCatch(expression: Function, paramsArgs: [str
return errorMessageForException(`Failed calculating expression "${arg}"`, e);
}
}

/**
* Evaluate an arbitrary JavaScript expression on a Task object
* @param task - a {@link Task} object
* @param arg - a string, such as `task.path.startsWith("journal/") ? "journal/" : task.path`
*
* Currently any errors are returned as string error messages, starting with the word 'Error'.
*
* @todo Implement a type-safe mechanism to report error messages distinct from expression results.
*
* See also {@link FunctionField} which exposes this facility to users.
*/
export function parseAndEvaluateExpression(task: Task, arg: string) {
const paramsArgs = constructArguments(task);

const functionOrError = parseExpression(paramsArgs, arg);
if (functionOrError.error) {
return functionOrError.error;
}

return evaluateExpressionOrCatch(functionOrError.queryComponent!, paramsArgs, arg);
}
44 changes: 37 additions & 7 deletions src/Scripting/TaskExpression.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,41 @@
import type { Task } from '../Task';
import {
FunctionOrError,
constructArguments,
evaluateExpression,
evaluateExpressionOrCatch,
parseExpression,
} from './Expression';
import { FunctionOrError, evaluateExpression, evaluateExpressionOrCatch, parseExpression } from './Expression';

/**
* From: https://www.educative.io/answers/parameter-vs-argument
* A parameter is a variable in a function definition. It is a placeholder and hence does not have a concrete value.
* An argument is a value passed during function invocation.
* @param task - during parsing, this can be null. During evaluation, it must be a Task
*/
export function constructArguments(task: Task | null) {
const paramsArgs: [string, any][] = [
// TODO Later, pass in the Query too, for access to file properties
['task', task],
];
return paramsArgs;
}

/**
* Evaluate an arbitrary JavaScript expression on a Task object
* @param task - a {@link Task} object
* @param arg - a string, such as `task.path.startsWith("journal/") ? "journal/" : task.path`
*
* Currently any errors are returned as string error messages, starting with the word 'Error'.
*
* @todo Implement a type-safe mechanism to report error messages distinct from expression results.
*
* See also {@link FunctionField} which exposes this facility to users.
*/
export function parseAndEvaluateExpression(task: Task, arg: string) {
const paramsArgs = constructArguments(task);

const functionOrError = parseExpression(paramsArgs, arg);
if (functionOrError.error) {
return functionOrError.error;
}

return evaluateExpressionOrCatch(functionOrError.queryComponent!, paramsArgs, arg);
}

/**
* Encapsulate an expression that can be calculated from a {@link Task} object
Expand Down
9 changes: 2 additions & 7 deletions tests/Scripting/Expression.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,11 @@
*/
import moment from 'moment';

import {
constructArguments,
evaluateExpression,
evaluateExpressionOrCatch,
parseAndEvaluateExpression,
parseExpression,
} from '../../src/Scripting/Expression';
import { evaluateExpression, evaluateExpressionOrCatch, parseExpression } from '../../src/Scripting/Expression';
import { TaskBuilder } from '../TestingTools/TaskBuilder';
import { verifyMarkdownForDocs } from '../TestingTools/VerifyMarkdownTable';
import { continue_lines } from '../../src/Query/Scanner';
import { constructArguments, parseAndEvaluateExpression } from '../../src/Scripting/TaskExpression';
import { formatToRepresentType } from './ScriptingTestHelpers';

window.moment = moment;
Expand Down
2 changes: 1 addition & 1 deletion tests/Scripting/TaskProperties.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
*/

import moment from 'moment';
import { parseAndEvaluateExpression } from '../../src/Scripting/Expression';
import { Status } from '../../src/Status';

import { TaskBuilder } from '../TestingTools/TaskBuilder';
import { MarkdownTable } from '../TestingTools/VerifyMarkdownTable';
import { parseAndEvaluateExpression } from '../../src/Scripting/TaskExpression';
import { addBackticks, determineExpressionType, formatToRepresentType } from './ScriptingTestHelpers';

window.moment = moment;
Expand Down

0 comments on commit c72cdcd

Please sign in to comment.