From 489287608573f9c4316681bc04979b3bc9176b78 Mon Sep 17 00:00:00 2001 From: gmickus Date: Wed, 27 Nov 2024 11:52:01 +0200 Subject: [PATCH 1/4] Create formatter --- package.json | 6 + src/model/SyntaxNodeType.ts | 7 + .../enableFormatterDecorators.ts | 2 + .../FunctionParameterFormatter.ts | 205 ++++++++++++++++++ .../FunctionParameterSettings.ts | 8 + 5 files changed, 228 insertions(+) create mode 100644 src/v2/formatters/functionParameter/FunctionParameterFormatter.ts create mode 100644 src/v2/formatters/functionParameter/FunctionParameterSettings.ts diff --git a/package.json b/package.json index 5f00268..6be6fc3 100644 --- a/package.json +++ b/package.json @@ -248,6 +248,12 @@ "default": "true", "description": "Enable PROCEDURE PARAMETER formatting" }, + "AblFormatter.functionParameterFormatting": { + "order": 1600, + "type": "boolean", + "default": "true", + "description": "Enable FUNCTION PARAMETER formatting" + }, "AblFormatter.showTreeInfoOnHover": { "order": 10100, "type": "boolean", diff --git a/src/model/SyntaxNodeType.ts b/src/model/SyntaxNodeType.ts index 8ba4d95..684f099 100644 --- a/src/model/SyntaxNodeType.ts +++ b/src/model/SyntaxNodeType.ts @@ -65,6 +65,8 @@ export enum SyntaxNodeType { LeftParenthesis = "(", RightParenthesis = ")", Label = "label", + Parameters = "parameters", + FunctionParameter = "function_parameter", // keywords WhenKeyword = "WHEN", @@ -137,3 +139,8 @@ export const parameterTypes = new MyFancySet([ SyntaxNodeType.InputOutputKeyword, SyntaxNodeType.ReturnKeyword, ]); + +export const parentheses = new MyFancySet([ + SyntaxNodeType.LeftParenthesis, + SyntaxNodeType.RightParenthesis, +]); diff --git a/src/v2/formatterFramework/enableFormatterDecorators.ts b/src/v2/formatterFramework/enableFormatterDecorators.ts index e18aa16..3660bca 100644 --- a/src/v2/formatterFramework/enableFormatterDecorators.ts +++ b/src/v2/formatterFramework/enableFormatterDecorators.ts @@ -13,6 +13,7 @@ import { BodyFormatter } from "../formatters/body/BodyFormatter"; import { EnumFormatter } from "../formatters/enum/EnumFormatter"; import { VariableDefinitionFormatter } from "../formatters/variableDefinition/VariableDefinitionFormatter"; import { ProcedureParameterFormatter } from "../formatters/procedureParameter/ProcedureParameterFormatter"; +import { FunctionParameterFormatter } from "../formatters/functionParameter/FunctionParameterFormatter"; // needed just for enabling decorators. Decorators does not work if there is no usage of a class in the reachable code export function enableFormatterDecorators(): void { @@ -31,4 +32,5 @@ export function enableFormatterDecorators(): void { VariableDefinitionFormatter; EnumFormatter; ProcedureParameterFormatter; + FunctionParameterFormatter; } diff --git a/src/v2/formatters/functionParameter/FunctionParameterFormatter.ts b/src/v2/formatters/functionParameter/FunctionParameterFormatter.ts new file mode 100644 index 0000000..3941acd --- /dev/null +++ b/src/v2/formatters/functionParameter/FunctionParameterFormatter.ts @@ -0,0 +1,205 @@ +import { SyntaxNode } from "web-tree-sitter"; +import { RegisterFormatter } from "../../formatterFramework/formatterDecorator"; +import { IFormatter } from "../../formatterFramework/IFormatter"; +import { CodeEdit } from "../../model/CodeEdit"; +import { FullText } from "../../model/FullText"; +import { AFormatter } from "../AFormatter"; +import { + definitionKeywords, + parameterTypes, + parentheses, + SyntaxNodeType, +} from "../../../model/SyntaxNodeType"; +import { FunctionParameterSettings } from "./FunctionParameterSettings"; +import { IConfigurationManager } from "../../../utils/IConfigurationManager"; +import { FormatterHelper } from "../../formatterFramework/FormatterHelper"; + +@RegisterFormatter +export class FunctionParameterFormatter + extends AFormatter + implements IFormatter +{ + public static readonly formatterLabel = "functionParamaterFormatting"; + private readonly settings: FunctionParameterSettings; + private alignType = 0; + private alignParameterType = 0; + private alignParameters = 0; + + public constructor(configurationManager: IConfigurationManager) { + super(configurationManager); + this.settings = new FunctionParameterSettings(configurationManager); + } + + match(node: Readonly): boolean { + if (node.type === SyntaxNodeType.Parameters) { + return true; + } + return false; + } + parse( + node: Readonly, + fullText: Readonly + ): CodeEdit | CodeEdit[] | undefined { + const oldText = FormatterHelper.getCurrentText(node, fullText); + const numberOfFunctionParameters = node.children.filter( + (child) => child.type === SyntaxNodeType.FunctionParameter + ).length; + + console.log("Parameters: " + numberOfFunctionParameters); + console.log("nodeParent: " + node.type); + node.children.forEach((child) => { + console.log("childType: " + child.type); + }); + + this.collectStructure(node, fullText); + console.log("alignType: " + this.alignType); + console.log("alignParameterType: " + this.alignParameterType); + const newText = this.collectString(node, fullText); + return this.getCodeEdit(node, oldText, newText, fullText); + } + + private collectString( + node: SyntaxNode, + fullText: Readonly + ): string { + let resultString = ""; + node.children.forEach((child) => { + resultString = resultString.concat(this.getString(child, fullText)); + }); + return resultString; + } + + private collectStructure( + node: SyntaxNode, + fullText: Readonly + ): void { + node.children.forEach((child) => { + this.getStructure(child, fullText); + }); + } + + private getStructure(node: SyntaxNode, fullText: Readonly): void { + switch (node.type) { + case SyntaxNodeType.LeftParenthesis: + this.alignParameters = node.startPosition.column + 1; + break; + case SyntaxNodeType.FunctionParameter: + node.children.forEach((child) => { + this.getParameterStructure(child, fullText); + }); + break; + } + } + + private getParameterStructure( + node: SyntaxNode, + fullText: Readonly + ): void { + switch (node.type) { + case SyntaxNodeType.Identifier: + this.alignType = Math.max( + this.alignType, + FormatterHelper.getCurrentText(node, fullText).trim().length + ); + break; + case parameterTypes.hasFancy(node.type, ""): + this.alignParameterType = Math.max( + this.alignParameterType, + FormatterHelper.getCurrentText(node, fullText).trim().length + ); + break; + } + } + private getString(node: SyntaxNode, fullText: Readonly): string { + let newString = ""; + switch (node.type) { + case parentheses.hasFancy(node.type, ""): + newString = FormatterHelper.getCurrentText( + node, + fullText + ).trim(); + break; + case SyntaxNodeType.FunctionParameter: + newString = this.collectParameterString(node, fullText); + break; + case SyntaxNodeType.CommaKeyword: + newString = + FormatterHelper.getCurrentText(node, fullText).trim() + + fullText.eolDelimiter + + " ".repeat(this.alignParameters); + break; + case SyntaxNodeType.Error: + newString = FormatterHelper.getCurrentText(node, fullText); + break; + default: { + const text = FormatterHelper.getCurrentText( + node, + fullText + ).trim(); + newString = text.length === 0 ? "" : " " + text; + break; + } + } + return newString; + } + + private collectParameterString( + node: SyntaxNode, + fullText: Readonly + ): string { + let resultString = ""; + node.children.forEach((child) => { + resultString = resultString.concat( + this.getParameterString(child, fullText) + ); + }); + return resultString; + } + + private getParameterString( + node: SyntaxNode, + fullText: Readonly + ): string { + let newString = ""; + switch (node.type) { + case SyntaxNodeType.DotKeyword: + break; + case definitionKeywords.hasFancy(node.type, ""): + newString = FormatterHelper.getCurrentText( + node, + fullText + ).trimEnd(); + break; + case SyntaxNodeType.Identifier: + const text = FormatterHelper.getCurrentText( + node, + fullText + ).trim(); + newString = text + " ".repeat(this.alignType - text.length); + break; + case parameterTypes.hasFancy(node.type, ""): { + const text = FormatterHelper.getCurrentText( + node, + fullText + ).trim(); + newString = + " " + + text + + " ".repeat(this.alignParameterType - text.length); + break; + } + case SyntaxNodeType.Error: + newString = FormatterHelper.getCurrentText(node, fullText); + break; + default: { + const text = FormatterHelper.getCurrentText( + node, + fullText + ).trim(); + newString = text.length === 0 ? "" : " " + text; + break; + } + } + return newString; + } +} diff --git a/src/v2/formatters/functionParameter/FunctionParameterSettings.ts b/src/v2/formatters/functionParameter/FunctionParameterSettings.ts new file mode 100644 index 0000000..3ed72c5 --- /dev/null +++ b/src/v2/formatters/functionParameter/FunctionParameterSettings.ts @@ -0,0 +1,8 @@ +import { ASettings } from "../ASettings"; + +export class FunctionParameterSettings extends ASettings { + // procedure parameter settings + public procedureParameterFormatting() { + return !!this.configurationManager.get("functionParamaterFormatting"); + } +} From 0f60d26f25c56e8924925d7995e94803546eaa80 Mon Sep 17 00:00:00 2001 From: gmickus Date: Wed, 27 Nov 2024 14:40:32 +0200 Subject: [PATCH 2/4] Update formatter, add tests --- package.json | 10 +++ .../block/20function-block-end3/input.p | 9 +-- .../57class-block-multiple-line copy/input.p | 6 ++ .../57class-block-multiple-line copy/target.p | 14 ++++ .../functionalTests/block/6do-end2/input.p | 7 +- .../{2-end-dot-new => 2-end-dot-new1}/input.p | 0 .../target.p | 0 .../input.p | 0 .../target.p | 0 .../functionParameter/1method/input.p | 8 ++ .../functionParameter/1method/target.p | 9 +++ .../functionParameter/2function/input.p | 7 ++ .../functionParameter/2function/target.p | 7 ++ .../3dataset-align-types/input.p | 11 +++ .../3dataset-align-types/target.p | 12 +++ .../functionParameter/3dataset-handle/input.p | 11 +++ .../3dataset-handle/target.p | 12 +++ .../functionParameter/3table-handle/input.p | 17 ++++ .../functionParameter/3table-handle/target.p | 17 ++++ .../functionParameter/4function copy/input.p | 9 +++ .../functionParameter/4function copy/target.p | 9 +++ .../functionParameter/4function/input.p | 8 ++ .../functionParameter/4function/target.p | 9 +++ src/model/SyntaxNodeType.ts | 1 + .../FunctionParameterFormatter.ts | 81 ++++++++++++++++--- .../FunctionParameterSettings.ts | 10 ++- 26 files changed, 264 insertions(+), 20 deletions(-) create mode 100644 resources/functionalTests/block/57class-block-multiple-line copy/input.p create mode 100644 resources/functionalTests/block/57class-block-multiple-line copy/target.p rename resources/functionalTests/enum/{2-end-dot-new => 2-end-dot-new1}/input.p (100%) rename resources/functionalTests/enum/{2-end-dot-new => 2-end-dot-new1}/target.p (100%) rename resources/functionalTests/enum/{2-end-dot-new copy => 2-end-dot-new2}/input.p (100%) rename resources/functionalTests/enum/{2-end-dot-new copy => 2-end-dot-new2}/target.p (100%) create mode 100644 resources/functionalTests/functionParameter/1method/input.p create mode 100644 resources/functionalTests/functionParameter/1method/target.p create mode 100644 resources/functionalTests/functionParameter/2function/input.p create mode 100644 resources/functionalTests/functionParameter/2function/target.p create mode 100644 resources/functionalTests/functionParameter/3dataset-align-types/input.p create mode 100644 resources/functionalTests/functionParameter/3dataset-align-types/target.p create mode 100644 resources/functionalTests/functionParameter/3dataset-handle/input.p create mode 100644 resources/functionalTests/functionParameter/3dataset-handle/target.p create mode 100644 resources/functionalTests/functionParameter/3table-handle/input.p create mode 100644 resources/functionalTests/functionParameter/3table-handle/target.p create mode 100644 resources/functionalTests/functionParameter/4function copy/input.p create mode 100644 resources/functionalTests/functionParameter/4function copy/target.p create mode 100644 resources/functionalTests/functionParameter/4function/input.p create mode 100644 resources/functionalTests/functionParameter/4function/target.p diff --git a/package.json b/package.json index 6be6fc3..01ef67b 100644 --- a/package.json +++ b/package.json @@ -254,6 +254,16 @@ "default": "true", "description": "Enable FUNCTION PARAMETER formatting" }, + "AblFormatter.functionParameterFormattingAlignParameterTypes": { + "order": 1601, + "type": "string", + "default": "Yes", + "enum": [ + "Yes", + "No" + ], + "description": "Align parameter types?" + }, "AblFormatter.showTreeInfoOnHover": { "order": 10100, "type": "boolean", diff --git a/resources/functionalTests/block/20function-block-end3/input.p b/resources/functionalTests/block/20function-block-end3/input.p index 99211ad..6668889 100644 --- a/resources/functionalTests/block/20function-block-end3/input.p +++ b/resources/functionalTests/block/20function-block-end3/input.p @@ -1,8 +1,7 @@ /* formatterSettingsOverride */ /* { "AblFormatter.blockFormatting": true}*/ -function fun returns integer (input p1 as integer, - input-output p2 as logical, - output p3 as character): - return p1. - end function. \ No newline at end of file +function GetDLC returns character +(): + define variable cValue as character no-undo. +end function. \ No newline at end of file diff --git a/resources/functionalTests/block/57class-block-multiple-line copy/input.p b/resources/functionalTests/block/57class-block-multiple-line copy/input.p new file mode 100644 index 0000000..09f325f --- /dev/null +++ b/resources/functionalTests/block/57class-block-multiple-line copy/input.p @@ -0,0 +1,6 @@ +/* formatterSettingsOverride */ +/* { "AblFormatter.blockFormatting": true}*/ +class Fun: + method public Table fill(poQuery as Query, poOnNotAvailable as QueryNotAvailable): + end method. +end class. \ No newline at end of file diff --git a/resources/functionalTests/block/57class-block-multiple-line copy/target.p b/resources/functionalTests/block/57class-block-multiple-line copy/target.p new file mode 100644 index 0000000..614aedf --- /dev/null +++ b/resources/functionalTests/block/57class-block-multiple-line copy/target.p @@ -0,0 +1,14 @@ +/* formatterSettingsOverride */ +/* { "AblFormatter.blockFormatting": true}*/ + +CLASS Validation.Something + INHERITS BaseStuff + IMPLEMENTS IThing + {&SERIALIZABLE}: + + METHOD PUBLIC OVERRIDE IType GetType(): + define VARIABLE oType AS IType NO-UNDO. + RETURN oType . + END METHOD. + +END CLASS. diff --git a/resources/functionalTests/block/6do-end2/input.p b/resources/functionalTests/block/6do-end2/input.p index 185c485..8ec170b 100644 --- a/resources/functionalTests/block/6do-end2/input.p +++ b/resources/functionalTests/block/6do-end2/input.p @@ -2,6 +2,7 @@ /* { "AblFormatter.blockFormatting": true}*/ do transaction: - do while true: - a = 3. end. - end. \ No newline at end of file + do while true: + a = 3. + end. +end. \ No newline at end of file diff --git a/resources/functionalTests/enum/2-end-dot-new/input.p b/resources/functionalTests/enum/2-end-dot-new1/input.p similarity index 100% rename from resources/functionalTests/enum/2-end-dot-new/input.p rename to resources/functionalTests/enum/2-end-dot-new1/input.p diff --git a/resources/functionalTests/enum/2-end-dot-new/target.p b/resources/functionalTests/enum/2-end-dot-new1/target.p similarity index 100% rename from resources/functionalTests/enum/2-end-dot-new/target.p rename to resources/functionalTests/enum/2-end-dot-new1/target.p diff --git a/resources/functionalTests/enum/2-end-dot-new copy/input.p b/resources/functionalTests/enum/2-end-dot-new2/input.p similarity index 100% rename from resources/functionalTests/enum/2-end-dot-new copy/input.p rename to resources/functionalTests/enum/2-end-dot-new2/input.p diff --git a/resources/functionalTests/enum/2-end-dot-new copy/target.p b/resources/functionalTests/enum/2-end-dot-new2/target.p similarity index 100% rename from resources/functionalTests/enum/2-end-dot-new copy/target.p rename to resources/functionalTests/enum/2-end-dot-new2/target.p diff --git a/resources/functionalTests/functionParameter/1method/input.p b/resources/functionalTests/functionParameter/1method/input.p new file mode 100644 index 0000000..fe7c169 --- /dev/null +++ b/resources/functionalTests/functionParameter/1method/input.p @@ -0,0 +1,8 @@ +/* formatterSettingsOverride */ +/* { "AblFormatter.functionParameterFormatting": true, + "AblFormatter.functionParameterFormattingAlignParameterTypes": "No"}*/ + +class FunClass: + method public Table fill(poQuery as Query, poOnNotAvailable as QueryNotAvailable): + end end method. +end class. \ No newline at end of file diff --git a/resources/functionalTests/functionParameter/1method/target.p b/resources/functionalTests/functionParameter/1method/target.p new file mode 100644 index 0000000..ac1bcf7 --- /dev/null +++ b/resources/functionalTests/functionParameter/1method/target.p @@ -0,0 +1,9 @@ +/* formatterSettingsOverride */ +/* { "AblFormatter.functionParameterFormatting": true, + "AblFormatter.functionParameterFormattingAlignParameterTypes": "No"}*/ + +class FunClass: + method public Table fill(poQuery as Query, + poOnNotAvailable as QueryNotAvailable): + end end method. +end class. \ No newline at end of file diff --git a/resources/functionalTests/functionParameter/2function/input.p b/resources/functionalTests/functionParameter/2function/input.p new file mode 100644 index 0000000..87af39b --- /dev/null +++ b/resources/functionalTests/functionParameter/2function/input.p @@ -0,0 +1,7 @@ +/* formatterSettingsOverride */ +/* { "AblFormatter.functionParameterFormatting": true, + "AblFormatter.functionParameterFormattingAlignParameterTypes": "Yes"}*/ + +FUNCTION doubler RETURNS INTEGER(INPUT parm1 AS INTEGER): + RETURN (2 * parm1). +END FUNCTION. \ No newline at end of file diff --git a/resources/functionalTests/functionParameter/2function/target.p b/resources/functionalTests/functionParameter/2function/target.p new file mode 100644 index 0000000..87af39b --- /dev/null +++ b/resources/functionalTests/functionParameter/2function/target.p @@ -0,0 +1,7 @@ +/* formatterSettingsOverride */ +/* { "AblFormatter.functionParameterFormatting": true, + "AblFormatter.functionParameterFormattingAlignParameterTypes": "Yes"}*/ + +FUNCTION doubler RETURNS INTEGER(INPUT parm1 AS INTEGER): + RETURN (2 * parm1). +END FUNCTION. \ No newline at end of file diff --git a/resources/functionalTests/functionParameter/3dataset-align-types/input.p b/resources/functionalTests/functionParameter/3dataset-align-types/input.p new file mode 100644 index 0000000..c69ca6a --- /dev/null +++ b/resources/functionalTests/functionParameter/3dataset-align-types/input.p @@ -0,0 +1,11 @@ +/* formatterSettingsOverride */ +/* { "AblFormatter.functionParameterFormatting": true, + "AblFormatter.functionParameterFormattingAlignParameterTypes": "Yes"}*/ + +class MyEntityClass: + method public void Fetch( input-output dataset dsMyDataset,poParameter2 as integer, + piParameterInteger as myParameter): + + end method. +end class. + diff --git a/resources/functionalTests/functionParameter/3dataset-align-types/target.p b/resources/functionalTests/functionParameter/3dataset-align-types/target.p new file mode 100644 index 0000000..3fd115e --- /dev/null +++ b/resources/functionalTests/functionParameter/3dataset-align-types/target.p @@ -0,0 +1,12 @@ +/* formatterSettingsOverride */ +/* { "AblFormatter.functionParameterFormatting": true, + "AblFormatter.functionParameterFormattingAlignParameterTypes": "Yes"}*/ + +class MyEntityClass: + method public void Fetch(input-output dataset dsMyDataset, + poParameter2 as integer, + piParameterInteger as myParameter): + + end method. +end class. + diff --git a/resources/functionalTests/functionParameter/3dataset-handle/input.p b/resources/functionalTests/functionParameter/3dataset-handle/input.p new file mode 100644 index 0000000..afe34c1 --- /dev/null +++ b/resources/functionalTests/functionParameter/3dataset-handle/input.p @@ -0,0 +1,11 @@ +/* formatterSettingsOverride */ +/* { "AblFormatter.functionParameterFormatting": true, + "AblFormatter.functionParameterFormattingAlignParameterTypes": "Yes"}*/ + +class FunkyWorld.Util.KittyLogHelper: + method private void SnuggleDataset(dataset-handle dsCuddlePuddle bind): + /* PURR */ + end method. +end class. + + \ No newline at end of file diff --git a/resources/functionalTests/functionParameter/3dataset-handle/target.p b/resources/functionalTests/functionParameter/3dataset-handle/target.p new file mode 100644 index 0000000..3fd115e --- /dev/null +++ b/resources/functionalTests/functionParameter/3dataset-handle/target.p @@ -0,0 +1,12 @@ +/* formatterSettingsOverride */ +/* { "AblFormatter.functionParameterFormatting": true, + "AblFormatter.functionParameterFormattingAlignParameterTypes": "Yes"}*/ + +class MyEntityClass: + method public void Fetch(input-output dataset dsMyDataset, + poParameter2 as integer, + piParameterInteger as myParameter): + + end method. +end class. + diff --git a/resources/functionalTests/functionParameter/3table-handle/input.p b/resources/functionalTests/functionParameter/3table-handle/input.p new file mode 100644 index 0000000..bcd684f --- /dev/null +++ b/resources/functionalTests/functionParameter/3table-handle/input.p @@ -0,0 +1,17 @@ +/* formatterSettingsOverride */ +/* { "AblFormatter.functionParameterFormatting": true, + "AblFormatter.functionParameterFormattingAlignParameterTypes": "Yes"}*/ + +class Olympus.Util.HermesHelper: + method public static void ExecuteOracleQuery (pcOracleString as character, + pcOlympianFields as character, + piNumProphecies as integer, + output table-handle phOracleTable): + + ZeusCollectorHelper:SmiteObject(hHermesQuery). + ZeusCollectorHelper:SmiteObject(hDionysusBuffer). + + end method. + +end class. + \ No newline at end of file diff --git a/resources/functionalTests/functionParameter/3table-handle/target.p b/resources/functionalTests/functionParameter/3table-handle/target.p new file mode 100644 index 0000000..183e158 --- /dev/null +++ b/resources/functionalTests/functionParameter/3table-handle/target.p @@ -0,0 +1,17 @@ +/* formatterSettingsOverride */ +/* { "AblFormatter.functionParameterFormatting": true, + "AblFormatter.functionParameterFormattingAlignParameterTypes": "Yes"}*/ + +class Olympus.Util.HermesHelper: + method public static void ExecuteOracleQuery(pcOracleString as character, + pcOlympianFields as character, + piNumProphecies as integer, + output table-handle phOracleTable): + + ZeusCollectorHelper:SmiteObject(hHermesQuery). + ZeusCollectorHelper:SmiteObject(hDionysusBuffer). + + end method. + +end class. + \ No newline at end of file diff --git a/resources/functionalTests/functionParameter/4function copy/input.p b/resources/functionalTests/functionParameter/4function copy/input.p new file mode 100644 index 0000000..7788335 --- /dev/null +++ b/resources/functionalTests/functionParameter/4function copy/input.p @@ -0,0 +1,9 @@ +/* formatterSettingsOverride */ +/* { "AblFormatter.functionParameterFormatting": true, + "AblFormatter.functionParameterFormattingAlignParameterTypes": "No"}*/ + +// TODO: add align function modes +function finalShot returns character (input myDribble as character, output tipOff as character): + +end function. + \ No newline at end of file diff --git a/resources/functionalTests/functionParameter/4function copy/target.p b/resources/functionalTests/functionParameter/4function copy/target.p new file mode 100644 index 0000000..bd5cd00 --- /dev/null +++ b/resources/functionalTests/functionParameter/4function copy/target.p @@ -0,0 +1,9 @@ +/* formatterSettingsOverride */ +/* { "AblFormatter.functionParameterFormatting": true, + "AblFormatter.functionParameterFormattingAlignParameterTypes": "No"}*/ + +function finalShot returns character (input myDribble as character, + output tipOff as character): + +end function. + \ No newline at end of file diff --git a/resources/functionalTests/functionParameter/4function/input.p b/resources/functionalTests/functionParameter/4function/input.p new file mode 100644 index 0000000..000ecbe --- /dev/null +++ b/resources/functionalTests/functionParameter/4function/input.p @@ -0,0 +1,8 @@ +/* formatterSettingsOverride */ +/* { "AblFormatter.functionParameterFormatting": true, + "AblFormatter.functionParameterFormattingAlignParameterTypes": "No"}*/ + +function finalShot returns character (input myDribble as character, output tipOff as character): + +end function. + \ No newline at end of file diff --git a/resources/functionalTests/functionParameter/4function/target.p b/resources/functionalTests/functionParameter/4function/target.p new file mode 100644 index 0000000..bd5cd00 --- /dev/null +++ b/resources/functionalTests/functionParameter/4function/target.p @@ -0,0 +1,9 @@ +/* formatterSettingsOverride */ +/* { "AblFormatter.functionParameterFormatting": true, + "AblFormatter.functionParameterFormattingAlignParameterTypes": "No"}*/ + +function finalShot returns character (input myDribble as character, + output tipOff as character): + +end function. + \ No newline at end of file diff --git a/src/model/SyntaxNodeType.ts b/src/model/SyntaxNodeType.ts index 684f099..b22ac2a 100644 --- a/src/model/SyntaxNodeType.ts +++ b/src/model/SyntaxNodeType.ts @@ -67,6 +67,7 @@ export enum SyntaxNodeType { Label = "label", Parameters = "parameters", FunctionParameter = "function_parameter", + FunctionParameterMode = "function_parameter_mode", // keywords WhenKeyword = "WHEN", diff --git a/src/v2/formatters/functionParameter/FunctionParameterFormatter.ts b/src/v2/formatters/functionParameter/FunctionParameterFormatter.ts index 3941acd..7dc7bfa 100644 --- a/src/v2/formatters/functionParameter/FunctionParameterFormatter.ts +++ b/src/v2/formatters/functionParameter/FunctionParameterFormatter.ts @@ -19,11 +19,12 @@ export class FunctionParameterFormatter extends AFormatter implements IFormatter { - public static readonly formatterLabel = "functionParamaterFormatting"; + public static readonly formatterLabel = "functionParameterFormatting"; private readonly settings: FunctionParameterSettings; private alignType = 0; private alignParameterType = 0; private alignParameters = 0; + private typeTuningInCurrentParameter = false; public constructor(configurationManager: IConfigurationManager) { super(configurationManager); @@ -45,16 +46,27 @@ export class FunctionParameterFormatter (child) => child.type === SyntaxNodeType.FunctionParameter ).length; - console.log("Parameters: " + numberOfFunctionParameters); - console.log("nodeParent: " + node.type); + // console.log("Parameters: " + numberOfFunctionParameters); + // console.log("nodeParent: " + node.type); + if ( + node.parent !== null && + node.parent.type === SyntaxNodeType.FunctionStatement && + numberOfFunctionParameters <= 1 + ) { + // In this case, if we try to format something, the code gets messed up. I'm not sure why, so for now we just don't format. + return undefined; + return this.getCodeEdit(node, oldText, oldText, fullText); + } node.children.forEach((child) => { - console.log("childType: " + child.type); + // console.log("childType: " + child.type); }); this.collectStructure(node, fullText); - console.log("alignType: " + this.alignType); - console.log("alignParameterType: " + this.alignParameterType); + // console.log("alignType: " + this.alignType); + // console.log("alignParameterType: " + this.alignParameterType); const newText = this.collectString(node, fullText); + // console.log("oldText: " + oldText); + // console.log("newText: " + newText); return this.getCodeEdit(node, oldText, newText, fullText); } @@ -147,6 +159,10 @@ export class FunctionParameterFormatter node: SyntaxNode, fullText: Readonly ): string { + this.typeTuningInCurrentParameter = node.children.some( + (child) => child.type === SyntaxNodeType.TypeTuning + ); + let resultString = ""; node.children.forEach((child) => { resultString = resultString.concat( @@ -162,20 +178,33 @@ export class FunctionParameterFormatter ): string { let newString = ""; switch (node.type) { - case SyntaxNodeType.DotKeyword: - break; - case definitionKeywords.hasFancy(node.type, ""): + case SyntaxNodeType.FunctionParameterMode: newString = FormatterHelper.getCurrentText( node, fullText - ).trimEnd(); + ).trim(); + + // Add a space because the structure is, for example, "INPUT identifier AS TypeTuning", so we need a space before the identifier. + if (this.typeTuningInCurrentParameter) { + newString += " "; + } break; case SyntaxNodeType.Identifier: const text = FormatterHelper.getCurrentText( node, fullText ).trim(); - newString = text + " ".repeat(this.alignType - text.length); + // No type-tuning implies that the type is DATASET, DATASET-HANDLE, TABLE or TABLE-HANDLE, and the identifier itself is not at the start of the parameter. + if (!this.typeTuningInCurrentParameter) { + newString = " " + text; + } else { + newString = this.settings.alignTypes() + ? text + " ".repeat(this.alignType - text.length) + : text; + } + break; + case SyntaxNodeType.TypeTuning: + newString = this.collectTypeTuningString(node, fullText); break; case parameterTypes.hasFancy(node.type, ""): { const text = FormatterHelper.getCurrentText( @@ -202,4 +231,34 @@ export class FunctionParameterFormatter } return newString; } + + private collectTypeTuningString( + node: SyntaxNode, + fullText: Readonly + ): string { + let resultString = ""; + node.children.forEach((child) => { + resultString = resultString.concat( + this.getTypeTuningString(child, fullText) + ); + }); + return resultString; + } + + private getTypeTuningString( + node: SyntaxNode, + fullText: Readonly + ): string { + let newString = ""; + const text = FormatterHelper.getCurrentText(node, fullText).trim(); + switch (node.type) { + case SyntaxNodeType.Error: + newString = FormatterHelper.getCurrentText(node, fullText); + break; + default: + newString = text.length === 0 ? "" : " " + text; + break; + } + return newString; + } } diff --git a/src/v2/formatters/functionParameter/FunctionParameterSettings.ts b/src/v2/formatters/functionParameter/FunctionParameterSettings.ts index 3ed72c5..33b8814 100644 --- a/src/v2/formatters/functionParameter/FunctionParameterSettings.ts +++ b/src/v2/formatters/functionParameter/FunctionParameterSettings.ts @@ -3,6 +3,14 @@ import { ASettings } from "../ASettings"; export class FunctionParameterSettings extends ASettings { // procedure parameter settings public procedureParameterFormatting() { - return !!this.configurationManager.get("functionParamaterFormatting"); + return !!this.configurationManager.get("functionParameterFormatting"); + } + + public alignTypes() { + return ( + this.configurationManager.get( + "functionParameterFormattingAlignParameterTypes" + ) === "Yes" + ); } } From dc75616c1f5a127d53b5453d2a9ccc78aa9a9718 Mon Sep 17 00:00:00 2001 From: gmickus Date: Wed, 27 Nov 2024 14:57:10 +0200 Subject: [PATCH 3/4] Add input, output, input-output align --- .../assign/2inFunction/input.p | 1 + .../assign/2inFunction/target.p | 1 + .../input.p | 5 ++-- .../target.p | 6 ++--- .../FunctionParameterFormatter.ts | 25 ++++++++++++++++--- 5 files changed, 28 insertions(+), 10 deletions(-) rename resources/functionalTests/functionParameter/{4function copy => 4function-align}/input.p (53%) rename resources/functionalTests/functionParameter/{4function copy => 4function-align}/target.p (51%) diff --git a/resources/functionalTests/assign/2inFunction/input.p b/resources/functionalTests/assign/2inFunction/input.p index ffe486b..7ed24f9 100644 --- a/resources/functionalTests/assign/2inFunction/input.p +++ b/resources/functionalTests/assign/2inFunction/input.p @@ -1,6 +1,7 @@ /* formatterSettingsOverride */ /* { "AblFormatter.assignFormatting": true, "abl.completion.upperCase": true, +"AblFormatter.functionParameterFormatting": false, "AblFormatter.assignFormattingAssignLocation": "New", "AblFormatter.assignFormattingAlignRightExpression": "Yes", "AblFormatter.assignFormattingEndDotLocation": "New aligned"}*/ diff --git a/resources/functionalTests/assign/2inFunction/target.p b/resources/functionalTests/assign/2inFunction/target.p index d811b42..3586de0 100644 --- a/resources/functionalTests/assign/2inFunction/target.p +++ b/resources/functionalTests/assign/2inFunction/target.p @@ -1,6 +1,7 @@ /* formatterSettingsOverride */ /* { "AblFormatter.assignFormatting": true, "abl.completion.upperCase": true, +"AblFormatter.functionParameterFormatting": false, "AblFormatter.assignFormattingAssignLocation": "New", "AblFormatter.assignFormattingAlignRightExpression": "Yes", "AblFormatter.assignFormattingEndDotLocation": "New aligned"}*/ diff --git a/resources/functionalTests/functionParameter/4function copy/input.p b/resources/functionalTests/functionParameter/4function-align/input.p similarity index 53% rename from resources/functionalTests/functionParameter/4function copy/input.p rename to resources/functionalTests/functionParameter/4function-align/input.p index 7788335..54277a2 100644 --- a/resources/functionalTests/functionParameter/4function copy/input.p +++ b/resources/functionalTests/functionParameter/4function-align/input.p @@ -1,9 +1,8 @@ /* formatterSettingsOverride */ /* { "AblFormatter.functionParameterFormatting": true, - "AblFormatter.functionParameterFormattingAlignParameterTypes": "No"}*/ + "AblFormatter.functionParameterFormattingAlignParameterTypes": "Yes"}*/ -// TODO: add align function modes -function finalShot returns character (input myDribble as character, output tipOff as character): +function finalShot returns character (input myDribbleShot as character, output tipOffAll as TipOff): end function. \ No newline at end of file diff --git a/resources/functionalTests/functionParameter/4function copy/target.p b/resources/functionalTests/functionParameter/4function-align/target.p similarity index 51% rename from resources/functionalTests/functionParameter/4function copy/target.p rename to resources/functionalTests/functionParameter/4function-align/target.p index bd5cd00..160def8 100644 --- a/resources/functionalTests/functionParameter/4function copy/target.p +++ b/resources/functionalTests/functionParameter/4function-align/target.p @@ -1,9 +1,9 @@ /* formatterSettingsOverride */ /* { "AblFormatter.functionParameterFormatting": true, - "AblFormatter.functionParameterFormattingAlignParameterTypes": "No"}*/ + "AblFormatter.functionParameterFormattingAlignParameterTypes": "Yes"}*/ -function finalShot returns character (input myDribble as character, - output tipOff as character): +function finalShot returns character (input myDribbleShot as character, + output tipOffAll as TipOff): end function. \ No newline at end of file diff --git a/src/v2/formatters/functionParameter/FunctionParameterFormatter.ts b/src/v2/formatters/functionParameter/FunctionParameterFormatter.ts index 7dc7bfa..be55ce4 100644 --- a/src/v2/formatters/functionParameter/FunctionParameterFormatter.ts +++ b/src/v2/formatters/functionParameter/FunctionParameterFormatter.ts @@ -23,6 +23,7 @@ export class FunctionParameterFormatter private readonly settings: FunctionParameterSettings; private alignType = 0; private alignParameterType = 0; + private alignParameterMode = 0; private alignParameters = 0; private typeTuningInCurrentParameter = false; @@ -46,12 +47,16 @@ export class FunctionParameterFormatter (child) => child.type === SyntaxNodeType.FunctionParameter ).length; + if (numberOfFunctionParameters === 0) { + return undefined; + } + // console.log("Parameters: " + numberOfFunctionParameters); // console.log("nodeParent: " + node.type); if ( node.parent !== null && node.parent.type === SyntaxNodeType.FunctionStatement && - numberOfFunctionParameters <= 1 + numberOfFunctionParameters === 1 ) { // In this case, if we try to format something, the code gets messed up. I'm not sure why, so for now we just don't format. return undefined; @@ -108,6 +113,12 @@ export class FunctionParameterFormatter fullText: Readonly ): void { switch (node.type) { + case SyntaxNodeType.FunctionParameterMode: + this.alignParameterMode = Math.max( + this.alignParameterMode, + FormatterHelper.getCurrentText(node, fullText).trim().length + ); + break; case SyntaxNodeType.Identifier: this.alignType = Math.max( this.alignType, @@ -179,17 +190,22 @@ export class FunctionParameterFormatter let newString = ""; switch (node.type) { case SyntaxNodeType.FunctionParameterMode: - newString = FormatterHelper.getCurrentText( + const text = FormatterHelper.getCurrentText( node, fullText ).trim(); + newString = text; // Add a space because the structure is, for example, "INPUT identifier AS TypeTuning", so we need a space before the identifier. if (this.typeTuningInCurrentParameter) { - newString += " "; + newString += " ".repeat( + this.settings.alignTypes() + ? this.alignParameterMode - text.length + 1 + : 1 + ); } break; - case SyntaxNodeType.Identifier: + case SyntaxNodeType.Identifier: { const text = FormatterHelper.getCurrentText( node, fullText @@ -203,6 +219,7 @@ export class FunctionParameterFormatter : text; } break; + } case SyntaxNodeType.TypeTuning: newString = this.collectTypeTuningString(node, fullText); break; From 77786f468699c5df66394fdb80bb195d924326bf Mon Sep 17 00:00:00 2001 From: gmickus Date: Fri, 29 Nov 2024 12:31:02 +0200 Subject: [PATCH 4/4] Update formatting for dataset, dataset-handle --- .../block/20function-block-end3/target.p | 7 +++---- .../block/25function-block-inner5/target.p | 4 ++-- .../block/57class-block-multiple-line copy/input.p | 6 ------ .../57class-block-multiple-line copy/target.p | 14 -------------- .../functionParameter/3dataset-handle/input.p | 4 +--- .../functionParameter/3dataset-handle/target.p | 11 ++++------- .../functionParameter/3table-handle/input.p | 5 ++--- .../functionParameter/3table-handle/target.p | 3 +-- .../functionParameter/4function-align/input.p | 3 +-- .../functionParameter/4function-align/target.p | 3 +-- src/model/SyntaxNodeType.ts | 11 +++++++++++ .../FunctionParameterFormatter.ts | 14 ++++++++++++++ 12 files changed, 40 insertions(+), 45 deletions(-) delete mode 100644 resources/functionalTests/block/57class-block-multiple-line copy/input.p delete mode 100644 resources/functionalTests/block/57class-block-multiple-line copy/target.p diff --git a/resources/functionalTests/block/20function-block-end3/target.p b/resources/functionalTests/block/20function-block-end3/target.p index a2db2df..6668889 100644 --- a/resources/functionalTests/block/20function-block-end3/target.p +++ b/resources/functionalTests/block/20function-block-end3/target.p @@ -1,8 +1,7 @@ /* formatterSettingsOverride */ /* { "AblFormatter.blockFormatting": true}*/ -function fun returns integer (input p1 as integer, - input-output p2 as logical, - output p3 as character): - return p1. +function GetDLC returns character +(): + define variable cValue as character no-undo. end function. \ No newline at end of file diff --git a/resources/functionalTests/block/25function-block-inner5/target.p b/resources/functionalTests/block/25function-block-inner5/target.p index a2db2df..8f49c04 100644 --- a/resources/functionalTests/block/25function-block-inner5/target.p +++ b/resources/functionalTests/block/25function-block-inner5/target.p @@ -1,8 +1,8 @@ /* formatterSettingsOverride */ /* { "AblFormatter.blockFormatting": true}*/ -function fun returns integer (input p1 as integer, +function fun returns integer (input p1 as integer, input-output p2 as logical, - output p3 as character): + output p3 as character): return p1. end function. \ No newline at end of file diff --git a/resources/functionalTests/block/57class-block-multiple-line copy/input.p b/resources/functionalTests/block/57class-block-multiple-line copy/input.p deleted file mode 100644 index 09f325f..0000000 --- a/resources/functionalTests/block/57class-block-multiple-line copy/input.p +++ /dev/null @@ -1,6 +0,0 @@ -/* formatterSettingsOverride */ -/* { "AblFormatter.blockFormatting": true}*/ -class Fun: - method public Table fill(poQuery as Query, poOnNotAvailable as QueryNotAvailable): - end method. -end class. \ No newline at end of file diff --git a/resources/functionalTests/block/57class-block-multiple-line copy/target.p b/resources/functionalTests/block/57class-block-multiple-line copy/target.p deleted file mode 100644 index 614aedf..0000000 --- a/resources/functionalTests/block/57class-block-multiple-line copy/target.p +++ /dev/null @@ -1,14 +0,0 @@ -/* formatterSettingsOverride */ -/* { "AblFormatter.blockFormatting": true}*/ - -CLASS Validation.Something - INHERITS BaseStuff - IMPLEMENTS IThing - {&SERIALIZABLE}: - - METHOD PUBLIC OVERRIDE IType GetType(): - define VARIABLE oType AS IType NO-UNDO. - RETURN oType . - END METHOD. - -END CLASS. diff --git a/resources/functionalTests/functionParameter/3dataset-handle/input.p b/resources/functionalTests/functionParameter/3dataset-handle/input.p index afe34c1..fe7768d 100644 --- a/resources/functionalTests/functionParameter/3dataset-handle/input.p +++ b/resources/functionalTests/functionParameter/3dataset-handle/input.p @@ -6,6 +6,4 @@ class FunkyWorld.Util.KittyLogHelper: method private void SnuggleDataset(dataset-handle dsCuddlePuddle bind): /* PURR */ end method. -end class. - - \ No newline at end of file +end class. \ No newline at end of file diff --git a/resources/functionalTests/functionParameter/3dataset-handle/target.p b/resources/functionalTests/functionParameter/3dataset-handle/target.p index 3fd115e..fe7768d 100644 --- a/resources/functionalTests/functionParameter/3dataset-handle/target.p +++ b/resources/functionalTests/functionParameter/3dataset-handle/target.p @@ -2,11 +2,8 @@ /* { "AblFormatter.functionParameterFormatting": true, "AblFormatter.functionParameterFormattingAlignParameterTypes": "Yes"}*/ -class MyEntityClass: - method public void Fetch(input-output dataset dsMyDataset, - poParameter2 as integer, - piParameterInteger as myParameter): - +class FunkyWorld.Util.KittyLogHelper: + method private void SnuggleDataset(dataset-handle dsCuddlePuddle bind): + /* PURR */ end method. -end class. - +end class. \ No newline at end of file diff --git a/resources/functionalTests/functionParameter/3table-handle/input.p b/resources/functionalTests/functionParameter/3table-handle/input.p index bcd684f..cabf127 100644 --- a/resources/functionalTests/functionParameter/3table-handle/input.p +++ b/resources/functionalTests/functionParameter/3table-handle/input.p @@ -3,7 +3,7 @@ "AblFormatter.functionParameterFormattingAlignParameterTypes": "Yes"}*/ class Olympus.Util.HermesHelper: - method public static void ExecuteOracleQuery (pcOracleString as character, + method public static void ExecuteOracleQuery(pcOracleString as character, pcOlympianFields as character, piNumProphecies as integer, output table-handle phOracleTable): @@ -13,5 +13,4 @@ class Olympus.Util.HermesHelper: end method. -end class. - \ No newline at end of file +end class. \ No newline at end of file diff --git a/resources/functionalTests/functionParameter/3table-handle/target.p b/resources/functionalTests/functionParameter/3table-handle/target.p index 183e158..c25a6da 100644 --- a/resources/functionalTests/functionParameter/3table-handle/target.p +++ b/resources/functionalTests/functionParameter/3table-handle/target.p @@ -13,5 +13,4 @@ class Olympus.Util.HermesHelper: end method. -end class. - \ No newline at end of file +end class. \ No newline at end of file diff --git a/resources/functionalTests/functionParameter/4function-align/input.p b/resources/functionalTests/functionParameter/4function-align/input.p index 54277a2..abb3087 100644 --- a/resources/functionalTests/functionParameter/4function-align/input.p +++ b/resources/functionalTests/functionParameter/4function-align/input.p @@ -4,5 +4,4 @@ function finalShot returns character (input myDribbleShot as character, output tipOffAll as TipOff): -end function. - \ No newline at end of file +end function. \ No newline at end of file diff --git a/resources/functionalTests/functionParameter/4function-align/target.p b/resources/functionalTests/functionParameter/4function-align/target.p index 160def8..15e7330 100644 --- a/resources/functionalTests/functionParameter/4function-align/target.p +++ b/resources/functionalTests/functionParameter/4function-align/target.p @@ -5,5 +5,4 @@ function finalShot returns character (input myDribbleShot as character, output tipOffAll as TipOff): -end function. - \ No newline at end of file +end function. \ No newline at end of file diff --git a/src/model/SyntaxNodeType.ts b/src/model/SyntaxNodeType.ts index b22ac2a..c8e9fcb 100644 --- a/src/model/SyntaxNodeType.ts +++ b/src/model/SyntaxNodeType.ts @@ -110,6 +110,10 @@ export enum SyntaxNodeType { ReturnKeyword = "RETURN", ParameterKeyword = "PARAMETER", VariableKeyword = "VARIABLE", + TableKeyword = "TABLE", + TableHandleKeyword = "TABLE-HANDLE", + DatasetKeyword = "DATASET", + DatasetHandleKeyword = "DATASET-HANDLE", } export const afterThenStatements = new MyFancySet([ @@ -127,6 +131,13 @@ export const definitionKeywords = new MyFancySet([ SyntaxNodeType.DefKeyword, ]); +export const dataStructureKeywords = new MyFancySet([ + SyntaxNodeType.TableKeyword, + SyntaxNodeType.TableHandleKeyword, + SyntaxNodeType.DatasetKeyword, + SyntaxNodeType.DatasetHandleKeyword, +]); + export const bodyBlockKeywords = new MyFancySet([ SyntaxNodeType.Body, SyntaxNodeType.CaseBody, diff --git a/src/v2/formatters/functionParameter/FunctionParameterFormatter.ts b/src/v2/formatters/functionParameter/FunctionParameterFormatter.ts index be55ce4..1a1d2a9 100644 --- a/src/v2/formatters/functionParameter/FunctionParameterFormatter.ts +++ b/src/v2/formatters/functionParameter/FunctionParameterFormatter.ts @@ -5,6 +5,7 @@ import { CodeEdit } from "../../model/CodeEdit"; import { FullText } from "../../model/FullText"; import { AFormatter } from "../AFormatter"; import { + dataStructureKeywords, definitionKeywords, parameterTypes, parentheses, @@ -26,6 +27,7 @@ export class FunctionParameterFormatter private alignParameterMode = 0; private alignParameters = 0; private typeTuningInCurrentParameter = false; + private parameterModeInCurrentParameter = false; public constructor(configurationManager: IConfigurationManager) { super(configurationManager); @@ -173,6 +175,9 @@ export class FunctionParameterFormatter this.typeTuningInCurrentParameter = node.children.some( (child) => child.type === SyntaxNodeType.TypeTuning ); + this.parameterModeInCurrentParameter = node.children.some( + (child) => child.type === SyntaxNodeType.FunctionParameterMode + ); let resultString = ""; node.children.forEach((child) => { @@ -189,6 +194,15 @@ export class FunctionParameterFormatter ): string { let newString = ""; switch (node.type) { + case dataStructureKeywords.hasFancy(node.type, ""): + newString = FormatterHelper.getCurrentText( + node, + fullText + ).trim(); + if (this.parameterModeInCurrentParameter) { + newString = " " + newString; + } + break; case SyntaxNodeType.FunctionParameterMode: const text = FormatterHelper.getCurrentText( node,