From 1bc5d7f400f10cd6fb91a457a5f98f6ff9ae0597 Mon Sep 17 00:00:00 2001 From: felix-oq <51856713+felix-oq@users.noreply.github.com> Date: Thu, 23 Mar 2023 10:04:31 +0100 Subject: [PATCH 1/2] Add TextRangeSelector block type --- libs/extensions/std/exec/src/extension.ts | 2 + .../exec/src/text-range-selector-executor.ts | 42 +++++++++++++++++++ libs/extensions/std/lang/src/extension.ts | 2 + .../lang/src/text-range-selector-meta-inf.ts | 29 +++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 libs/extensions/std/exec/src/text-range-selector-executor.ts create mode 100644 libs/extensions/std/lang/src/text-range-selector-meta-inf.ts diff --git a/libs/extensions/std/exec/src/extension.ts b/libs/extensions/std/exec/src/extension.ts index 37912ea25..5a7706e0a 100644 --- a/libs/extensions/std/exec/src/extension.ts +++ b/libs/extensions/std/exec/src/extension.ts @@ -6,6 +6,7 @@ import { ArchiveInterpreterExecutor } from './archive-interpreter-executor'; import { FilePickerExecutor } from './file-picker-executor'; import { HttpExtractorExecutor } from './http-extractor-executor'; import { TextFileInterpreterExecutor } from './text-file-interpreter-executor'; +import { TextRangeSelectorExecutor } from './text-range-selector-executor'; export class StdExecExtension implements JayveeExecExtension { private readonly wrappedExtensions: JayveeExecExtension[] = [ @@ -18,6 +19,7 @@ export class StdExecExtension implements JayveeExecExtension { ...this.wrappedExtensions.map((x) => x.getBlockExecutors()).flat(), HttpExtractorExecutor, TextFileInterpreterExecutor, + TextRangeSelectorExecutor, ArchiveInterpreterExecutor, FilePickerExecutor, ]; diff --git a/libs/extensions/std/exec/src/text-range-selector-executor.ts b/libs/extensions/std/exec/src/text-range-selector-executor.ts new file mode 100644 index 000000000..610349acf --- /dev/null +++ b/libs/extensions/std/exec/src/text-range-selector-executor.ts @@ -0,0 +1,42 @@ +import * as R from '@jvalue/execution'; +import { + BlockExecutor, + BlockExecutorClass, + ExecutionContext, + TextFile, + implementsStatic, +} from '@jvalue/execution'; +import { IOType } from '@jvalue/language-server'; + +@implementsStatic() +export class TextRangeSelectorExecutor + implements BlockExecutor +{ + public static readonly type = 'TextRangeSelector'; + public readonly inputType = IOType.TEXT_FILE; + public readonly outputType = IOType.TEXT_FILE; + + // eslint-disable-next-line @typescript-eslint/require-await + async execute( + file: TextFile, + context: ExecutionContext, + ): Promise> { + const lineFrom = context.getNumericPropertyValue('lineFrom'); + const lineTo = context.getNumericPropertyValue('lineTo'); + + const numberOfLines = file.content.length; + + context.logger.logDebug( + `Selecting lines from ${lineFrom} to ${ + lineTo === Number.POSITIVE_INFINITY || lineTo >= numberOfLines + ? 'the end' + : `${lineTo}` + }`, + ); + const selectedLines = file.content.slice(lineFrom - 1, lineTo); + + return R.ok( + new TextFile(file.name, file.extension, file.mimeType, selectedLines), + ); + } +} diff --git a/libs/extensions/std/lang/src/extension.ts b/libs/extensions/std/lang/src/extension.ts index 072e495e7..622965fd2 100644 --- a/libs/extensions/std/lang/src/extension.ts +++ b/libs/extensions/std/lang/src/extension.ts @@ -10,6 +10,7 @@ import { ArchiveInterpreterMetaInformation } from './archive-interpreter-meta-in import { FilePickerMetaInformation } from './file-picker-meta-inf'; import { HttpExtractorMetaInformation } from './http-extractor-meta-inf'; import { TextFileInterpreterMetaInformation } from './text-file-interpreter-meta-inf'; +import { TextRangeSelectorMetaInformation } from './text-range-selector-meta-inf'; export class StdLangExtension implements JayveeLangExtension { private readonly wrappedExtensions: JayveeLangExtension[] = [ @@ -22,6 +23,7 @@ export class StdLangExtension implements JayveeLangExtension { ...this.wrappedExtensions.map((x) => x.getBlockMetaInf()).flat(), HttpExtractorMetaInformation, TextFileInterpreterMetaInformation, + TextRangeSelectorMetaInformation, ArchiveInterpreterMetaInformation, FilePickerMetaInformation, ]; diff --git a/libs/extensions/std/lang/src/text-range-selector-meta-inf.ts b/libs/extensions/std/lang/src/text-range-selector-meta-inf.ts new file mode 100644 index 000000000..92a6b8a80 --- /dev/null +++ b/libs/extensions/std/lang/src/text-range-selector-meta-inf.ts @@ -0,0 +1,29 @@ +import { + BlockMetaInformation, + IOType, + PropertyValuetype, +} from '@jvalue/language-server'; + +export class TextRangeSelectorMetaInformation extends BlockMetaInformation { + constructor() { + super( + 'TextRangeSelector', + { + lineFrom: { + type: PropertyValuetype.INTEGER, + defaultValue: 1, + }, + lineTo: { + type: PropertyValuetype.INTEGER, + defaultValue: Number.POSITIVE_INFINITY, + }, + }, + // Input type: + IOType.TEXT_FILE, + + // Output type: + IOType.TEXT_FILE, + ); + this.docs.description = 'Selects a range of lines from a `TextFile`.'; + } +} From bff6d252d1bdc26e0c93d4a305368c1f31470507 Mon Sep 17 00:00:00 2001 From: felix-oq <51856713+felix-oq@users.noreply.github.com> Date: Thu, 23 Mar 2023 13:48:17 +0100 Subject: [PATCH 2/2] Add positivity validation for line numbers --- .../lang/src/text-range-selector-meta-inf.ts | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/libs/extensions/std/lang/src/text-range-selector-meta-inf.ts b/libs/extensions/std/lang/src/text-range-selector-meta-inf.ts index 92a6b8a80..adf5cf8d7 100644 --- a/libs/extensions/std/lang/src/text-range-selector-meta-inf.ts +++ b/libs/extensions/std/lang/src/text-range-selector-meta-inf.ts @@ -1,8 +1,13 @@ +import { strict as assert } from 'assert'; + import { BlockMetaInformation, IOType, + PropertyAssignment, PropertyValuetype, + isNumericLiteral, } from '@jvalue/language-server'; +import { ValidationAcceptor } from 'langium'; export class TextRangeSelectorMetaInformation extends BlockMetaInformation { constructor() { @@ -12,10 +17,12 @@ export class TextRangeSelectorMetaInformation extends BlockMetaInformation { lineFrom: { type: PropertyValuetype.INTEGER, defaultValue: 1, + validation: greaterThanZeroValidation, }, lineTo: { type: PropertyValuetype.INTEGER, defaultValue: Number.POSITIVE_INFINITY, + validation: greaterThanZeroValidation, }, }, // Input type: @@ -27,3 +34,17 @@ export class TextRangeSelectorMetaInformation extends BlockMetaInformation { this.docs.description = 'Selects a range of lines from a `TextFile`.'; } } + +function greaterThanZeroValidation( + property: PropertyAssignment, + accept: ValidationAcceptor, +) { + const propertyValue = property.value; + assert(isNumericLiteral(propertyValue)); + + if (propertyValue.value <= 0) { + accept('error', `Line numbers need to be greater than zero`, { + node: propertyValue, + }); + } +}