From 3a204decee6d09190cfa8d5cdb43b238999bf1ad Mon Sep 17 00:00:00 2001 From: QuickWrite <54590845+QuickWrite@users.noreply.github.com> Date: Sun, 9 Oct 2022 15:52:55 +0200 Subject: [PATCH 1/6] Make a bundle for the arguments in the tree --- .../quickwrite/fluent4j/ast/FluentBase.java | 24 ++++--------------- .../fluent4j/ast/FluentElement.java | 7 +++--- .../fluent4j/ast/FluentTextElement.java | 4 ++-- .../fluent4j/ast/FluentVariant.java | 6 ++--- .../ast/placeable/AttributeReference.java | 11 +++++---- .../ast/placeable/FunctionReference.java | 17 +++++++------ .../ast/placeable/MessageReference.java | 7 +++--- .../fluent4j/ast/placeable/NumberLiteral.java | 6 ++--- .../ast/placeable/SelectExpression.java | 12 +++++----- .../fluent4j/ast/placeable/StringLiteral.java | 4 ++-- .../fluent4j/ast/placeable/TermReference.java | 14 +++++------ .../ast/placeable/VariableReference.java | 10 ++++---- .../placeable/base/FluentArgumentResult.java | 5 ++-- .../ast/placeable/base/FluentFunction.java | 12 ++++------ .../fluent4j/functions/AbstractFunction.java | 3 ++- .../fluent4j/functions/NumberFunction.java | 4 ++-- .../util/args/CustomNumberLiteral.java | 6 ++--- .../fluent4j/util/args/FluentArgs.java | 7 +++--- .../fluent4j/util/args/FluentArguments.java | 6 ++--- .../util/args/FunctionFluentArguments.java | 8 +++---- .../util/bundle/DirectFluentBundle.java | 3 --- .../util/bundle/ResourceFluentBundle.java | 7 +++++- .../util/bundle/args/AccessorBundle.java | 10 ++++++++ .../bundle/args/AccessorElementsBundle.java | 24 +++++++++++++++++++ .../fluent4j/TestCallExpressions.java | 7 +++--- 25 files changed, 122 insertions(+), 102 deletions(-) create mode 100644 src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessorBundle.java create mode 100644 src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessorElementsBundle.java diff --git a/src/main/java/net/quickwrite/fluent4j/ast/FluentBase.java b/src/main/java/net/quickwrite/fluent4j/ast/FluentBase.java index d12ac430..0e3a24c0 100644 --- a/src/main/java/net/quickwrite/fluent4j/ast/FluentBase.java +++ b/src/main/java/net/quickwrite/fluent4j/ast/FluentBase.java @@ -3,8 +3,8 @@ import net.quickwrite.fluent4j.exception.FluentParseException; import net.quickwrite.fluent4j.util.StringSlice; import net.quickwrite.fluent4j.util.StringSliceUtil; -import net.quickwrite.fluent4j.util.args.FluentArgs; import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; import java.util.LinkedList; import java.util.List; @@ -88,32 +88,16 @@ public String getIdentifier() { return this.identifier; } - private StringSlice getVariantIdentifier(final StringSlice content) { - char character = content.getChar(); - final int start = content.getPosition(); - - while (character != ' ' - && character != '\n' - && character != ']' - && character != '\0' - ) { - content.increment(); - character = content.getChar(); - } - - return content.substring(start, content.getPosition()); - } - @Override - public CharSequence getResult(final DirectFluentBundle bundle, final FluentArgs arguments) { + public CharSequence getResult(final AccessorBundle bundle) { if (this.fluentElements.size() == 1) { - return this.fluentElements.get(0).getResult(bundle, arguments); + return this.fluentElements.get(0).getResult(bundle); } final StringBuilder builder = new StringBuilder(); for (final FluentElement element : this.fluentElements) { - builder.append(element.getResult(bundle, arguments)); + builder.append(element.getResult(bundle)); } return builder; diff --git a/src/main/java/net/quickwrite/fluent4j/ast/FluentElement.java b/src/main/java/net/quickwrite/fluent4j/ast/FluentElement.java index 3d00ba23..1e58a41e 100644 --- a/src/main/java/net/quickwrite/fluent4j/ast/FluentElement.java +++ b/src/main/java/net/quickwrite/fluent4j/ast/FluentElement.java @@ -2,8 +2,8 @@ import net.quickwrite.fluent4j.ast.placeable.NumberLiteral; import net.quickwrite.fluent4j.ast.placeable.SelectExpression; -import net.quickwrite.fluent4j.util.args.FluentArgs; import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; /** * The base interface for the AST. @@ -41,9 +41,8 @@ public interface FluentElement { * the different arguments and the base bundle that * it has been called from. * - * @param bundle The base bundle - * @param arguments The arguments that are being passed on the scope + * @param bundle The bundle that is getting passed down * @return The {@link CharSequence} value of the argument with the parameters */ - CharSequence getResult(final DirectFluentBundle bundle, final FluentArgs arguments); + CharSequence getResult(final AccessorBundle bundle); } diff --git a/src/main/java/net/quickwrite/fluent4j/ast/FluentTextElement.java b/src/main/java/net/quickwrite/fluent4j/ast/FluentTextElement.java index 6fcae2f0..d83abb53 100644 --- a/src/main/java/net/quickwrite/fluent4j/ast/FluentTextElement.java +++ b/src/main/java/net/quickwrite/fluent4j/ast/FluentTextElement.java @@ -1,8 +1,8 @@ package net.quickwrite.fluent4j.ast; -import net.quickwrite.fluent4j.util.args.FluentArgs; import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; import net.quickwrite.fluent4j.util.StringSlice; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; /** * The TextElement is just storing a text that does @@ -82,7 +82,7 @@ public String stringValue() { } @Override - public CharSequence getResult(DirectFluentBundle bundle, FluentArgs arguments) { + public CharSequence getResult(AccessorBundle bundle) { return this.text; } diff --git a/src/main/java/net/quickwrite/fluent4j/ast/FluentVariant.java b/src/main/java/net/quickwrite/fluent4j/ast/FluentVariant.java index be73cabe..7e972c69 100644 --- a/src/main/java/net/quickwrite/fluent4j/ast/FluentVariant.java +++ b/src/main/java/net/quickwrite/fluent4j/ast/FluentVariant.java @@ -1,11 +1,11 @@ package net.quickwrite.fluent4j.ast; import net.quickwrite.fluent4j.exception.FluentParseException; -import net.quickwrite.fluent4j.util.args.FluentArgs; import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; import net.quickwrite.fluent4j.ast.placeable.NumberLiteral; import net.quickwrite.fluent4j.ast.placeable.StringLiteral; import net.quickwrite.fluent4j.ast.placeable.base.FluentPlaceable; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; /** * A variant stores a single variant of a @@ -53,8 +53,8 @@ public String stringValue() { return identifier.stringValue(); } - public CharSequence getResult(final DirectFluentBundle bundle, final FluentArgs arguments) { - return this.content.getResult(bundle, arguments); + public CharSequence getResult(AccessorBundle bundle) { + return this.content.getResult(bundle); } @Override diff --git a/src/main/java/net/quickwrite/fluent4j/ast/placeable/AttributeReference.java b/src/main/java/net/quickwrite/fluent4j/ast/placeable/AttributeReference.java index 4652fbfb..3dd61ded 100644 --- a/src/main/java/net/quickwrite/fluent4j/ast/placeable/AttributeReference.java +++ b/src/main/java/net/quickwrite/fluent4j/ast/placeable/AttributeReference.java @@ -9,6 +9,7 @@ import net.quickwrite.fluent4j.util.StringSlice; import net.quickwrite.fluent4j.util.args.FluentArgs; import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; import java.util.List; @@ -41,8 +42,8 @@ public String stringValue() { } @Override - public CharSequence getResult(final DirectFluentBundle bundle, final FluentArgs arguments) { - final FluentMessage fluentMessage = this.getMessage(bundle, reference.stringValue()); + public CharSequence getResult(final AccessorBundle bundle) { + final FluentMessage fluentMessage = this.getMessage(bundle.getBundle(), reference.stringValue()); if (fluentMessage == null) { return getErrorString(); } @@ -53,12 +54,12 @@ public CharSequence getResult(final DirectFluentBundle bundle, final FluentArgs return getErrorString(); } - return attribute.getResult(bundle, getArguments(arguments)); + return attribute.getResult(bundle); } @Override - public FluentElement getArgumentResult(final DirectFluentBundle bundle, final FluentArgs arguments) { - final FluentMessage fluentMessage = this.getMessage(bundle, reference.stringValue()); + public FluentElement getArgumentResult(final AccessorBundle bundle) { + final FluentMessage fluentMessage = this.getMessage(bundle.getBundle(), reference.stringValue()); if (fluentMessage == null) { return this; } diff --git a/src/main/java/net/quickwrite/fluent4j/ast/placeable/FunctionReference.java b/src/main/java/net/quickwrite/fluent4j/ast/placeable/FunctionReference.java index 425b067d..ad598312 100644 --- a/src/main/java/net/quickwrite/fluent4j/ast/placeable/FunctionReference.java +++ b/src/main/java/net/quickwrite/fluent4j/ast/placeable/FunctionReference.java @@ -3,10 +3,9 @@ import net.quickwrite.fluent4j.ast.FluentElement; import net.quickwrite.fluent4j.ast.placeable.base.FluentFunction; import net.quickwrite.fluent4j.ast.placeable.base.FluentSelectable; -import net.quickwrite.fluent4j.util.StringSlice; import net.quickwrite.fluent4j.util.args.FluentArgs; import net.quickwrite.fluent4j.util.args.FunctionFluentArgs; -import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; /** * Functions provide additional functionality available to the localizers. @@ -21,12 +20,13 @@ public FunctionReference(final String functionName, final FluentArgs arguments) } @Override - public FluentElement getArgumentResult(final DirectFluentBundle bundle, final FluentArgs arguments) { + public FluentElement getArgumentResult(final AccessorBundle bundle) { try { return bundle + .getBundle() .getFunction(this.functionName) .orElseThrow() - .getResult(bundle, (FunctionFluentArgs) this.getArguments(bundle, arguments)); + .getResult(bundle, (FunctionFluentArgs) this.getArguments(bundle)); } catch (final Exception exception) { return new StringLiteral("{" + functionName + "()}"); } @@ -69,13 +69,12 @@ protected boolean check(String string) { * This means that the {@code NUMBER}-function gets no arguments * this function will return {NUMBER()}. * - * @param bundle The base bundle - * @param arguments The arguments that are being passed on the scope - * @return The result of the function with the specific parameters + * + * @param bundle@return The result of the function with the specific parameters */ @Override - public CharSequence getResult(final DirectFluentBundle bundle, final FluentArgs arguments) { - return this.getArgumentResult(bundle, arguments).getResult(bundle, arguments); + public CharSequence getResult(AccessorBundle bundle) { + return this.getArgumentResult(bundle).getResult(bundle); } @Override diff --git a/src/main/java/net/quickwrite/fluent4j/ast/placeable/MessageReference.java b/src/main/java/net/quickwrite/fluent4j/ast/placeable/MessageReference.java index 5d9c5444..604959d6 100644 --- a/src/main/java/net/quickwrite/fluent4j/ast/placeable/MessageReference.java +++ b/src/main/java/net/quickwrite/fluent4j/ast/placeable/MessageReference.java @@ -3,8 +3,8 @@ import net.quickwrite.fluent4j.ast.FluentElement; import net.quickwrite.fluent4j.ast.placeable.base.FluentPlaceable; import net.quickwrite.fluent4j.util.StringSlice; -import net.quickwrite.fluent4j.util.args.FluentArgs; import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; /** @@ -36,9 +36,10 @@ public String stringValue() { } @Override - public CharSequence getResult(final DirectFluentBundle bundle, final FluentArgs arguments) { + public CharSequence getResult(final AccessorBundle bundle) { return bundle - .getMessage(this.stringValue(), arguments) + .getBundle() + .getMessage(this.stringValue(), bundle.getArguments()) .orElse("{" + this.stringValue() + "}"); } diff --git a/src/main/java/net/quickwrite/fluent4j/ast/placeable/NumberLiteral.java b/src/main/java/net/quickwrite/fluent4j/ast/placeable/NumberLiteral.java index 36a7cfae..7f7ba584 100644 --- a/src/main/java/net/quickwrite/fluent4j/ast/placeable/NumberLiteral.java +++ b/src/main/java/net/quickwrite/fluent4j/ast/placeable/NumberLiteral.java @@ -10,9 +10,9 @@ import net.quickwrite.fluent4j.ast.placeable.base.FluentPlaceable; import net.quickwrite.fluent4j.ast.placeable.base.FluentSelectable; import net.quickwrite.fluent4j.util.StringSlice; -import net.quickwrite.fluent4j.util.args.FluentArgs; import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; import java.math.BigDecimal; @@ -51,8 +51,8 @@ public static NumberLiteral getNumberLiteral(final String value) { } @Override - public CharSequence getResult(final DirectFluentBundle bundle, final FluentArgs arguments) { - return NumberFormat.getInstance(bundle.getLocale()).format(number); + public CharSequence getResult(final AccessorBundle bundle) { + return NumberFormat.getInstance(bundle.getBundle().getLocale()).format(number); } private static BigDecimal convertToBigDecimal(final Number number) { diff --git a/src/main/java/net/quickwrite/fluent4j/ast/placeable/SelectExpression.java b/src/main/java/net/quickwrite/fluent4j/ast/placeable/SelectExpression.java index 8927e77c..b4c6fc94 100644 --- a/src/main/java/net/quickwrite/fluent4j/ast/placeable/SelectExpression.java +++ b/src/main/java/net/quickwrite/fluent4j/ast/placeable/SelectExpression.java @@ -4,8 +4,8 @@ import net.quickwrite.fluent4j.ast.FluentVariant; import net.quickwrite.fluent4j.ast.placeable.base.FluentArgumentResult; import net.quickwrite.fluent4j.ast.placeable.base.FluentPlaceable; -import net.quickwrite.fluent4j.util.args.FluentArgs; import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; import java.util.List; @@ -50,17 +50,17 @@ public String stringValue() { } @Override - public CharSequence getResult(final DirectFluentBundle bundle, final FluentArgs arguments) { + public CharSequence getResult(final AccessorBundle bundle) { final FluentElement argument = (identifier instanceof FluentArgumentResult) ? - ((FluentArgumentResult) identifier).getArgumentResult(bundle, arguments) : identifier; + ((FluentArgumentResult) identifier).getArgumentResult(bundle) : identifier; for (final FluentVariant variant : variants) { - if (argument.matches(bundle, variant.getIdentifier())) { - return variant.getResult(bundle, arguments); + if (argument.matches(bundle.getBundle(), variant.getIdentifier())) { + return variant.getResult(bundle); } } - return defaultVariant.getResult(bundle, arguments); + return defaultVariant.getResult(bundle); } @Override diff --git a/src/main/java/net/quickwrite/fluent4j/ast/placeable/StringLiteral.java b/src/main/java/net/quickwrite/fluent4j/ast/placeable/StringLiteral.java index 7a957cd8..79f07710 100644 --- a/src/main/java/net/quickwrite/fluent4j/ast/placeable/StringLiteral.java +++ b/src/main/java/net/quickwrite/fluent4j/ast/placeable/StringLiteral.java @@ -5,8 +5,8 @@ import net.quickwrite.fluent4j.ast.placeable.base.FluentSelectable; import net.quickwrite.fluent4j.ast.placeable.base.FluentUnicodeTranslator; import net.quickwrite.fluent4j.util.StringSlice; -import net.quickwrite.fluent4j.util.args.FluentArgs; import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; import org.apache.commons.text.translate.AggregateTranslator; import org.apache.commons.text.translate.CharSequenceTranslator; import org.apache.commons.text.translate.LookupTranslator; @@ -55,7 +55,7 @@ public StringLiteral(final String content) { } @Override - public CharSequence getResult(final DirectFluentBundle bundle, final FluentArgs arguments) { + public CharSequence getResult(AccessorBundle bundle) { return this.literal; } diff --git a/src/main/java/net/quickwrite/fluent4j/ast/placeable/TermReference.java b/src/main/java/net/quickwrite/fluent4j/ast/placeable/TermReference.java index d3cad0c5..35acd2f5 100644 --- a/src/main/java/net/quickwrite/fluent4j/ast/placeable/TermReference.java +++ b/src/main/java/net/quickwrite/fluent4j/ast/placeable/TermReference.java @@ -5,7 +5,8 @@ import net.quickwrite.fluent4j.ast.placeable.base.FluentFunction; import net.quickwrite.fluent4j.util.StringSlice; import net.quickwrite.fluent4j.util.args.FluentArgs; -import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; +import net.quickwrite.fluent4j.util.bundle.args.AccessorElementsBundle; /** * Terms are similar to regular messages but they can @@ -39,18 +40,17 @@ protected boolean check(final String string) { } @Override - public CharSequence getResult(final DirectFluentBundle bundle, final FluentArgs arguments) { - return this.getArgumentResult(bundle, arguments).getResult(bundle, this.getArguments(bundle, arguments)); + public CharSequence getResult(final AccessorBundle bundle) { + return this.getArgumentResult(bundle).getResult(new AccessorElementsBundle(bundle.getBundle(), arguments)); } /** * @param bundle The bundle that this is being called from - * @param arguments The arguments that are passed into this function - * @return + * @return The result of the term that is being called */ @Override - public FluentElement getArgumentResult(final DirectFluentBundle bundle, final FluentArgs arguments) { - final FluentTerm term = bundle.getTerm(this.functionName); + public FluentElement getArgumentResult(final AccessorBundle bundle) { + final FluentTerm term = bundle.getBundle().getTerm(this.functionName); if (term == null) { return new StringLiteral("{-" + this.functionName + "}"); diff --git a/src/main/java/net/quickwrite/fluent4j/ast/placeable/VariableReference.java b/src/main/java/net/quickwrite/fluent4j/ast/placeable/VariableReference.java index 9d2db2c2..4da95b1d 100644 --- a/src/main/java/net/quickwrite/fluent4j/ast/placeable/VariableReference.java +++ b/src/main/java/net/quickwrite/fluent4j/ast/placeable/VariableReference.java @@ -7,6 +7,7 @@ import net.quickwrite.fluent4j.util.StringSlice; import net.quickwrite.fluent4j.util.args.FluentArgs; import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; /** * Variables are pieces of data received from the app. @@ -51,7 +52,8 @@ public String stringValue() { } @Override - public FluentElement getArgumentResult(DirectFluentBundle bundle, final FluentArgs arguments) { + public FluentElement getArgumentResult(final AccessorBundle bundle) { + final FluentArgs arguments = bundle.getArguments(); final FluentElement argument = arguments.getNamed(content); if (argument == null) { @@ -62,14 +64,14 @@ public FluentElement getArgumentResult(DirectFluentBundle bundle, final FluentAr } @Override - public CharSequence getResult(final DirectFluentBundle bundle, final FluentArgs arguments) { - final FluentElement argument = arguments.getNamed(content); + public CharSequence getResult(final AccessorBundle bundle) { + final FluentElement argument = bundle.getArguments().getNamed(content); if (argument == null) { return "{$" + content + "}"; } - return argument.getResult(bundle, arguments); + return argument.getResult(bundle); } @Override diff --git a/src/main/java/net/quickwrite/fluent4j/ast/placeable/base/FluentArgumentResult.java b/src/main/java/net/quickwrite/fluent4j/ast/placeable/base/FluentArgumentResult.java index 24be38b8..79827a80 100644 --- a/src/main/java/net/quickwrite/fluent4j/ast/placeable/base/FluentArgumentResult.java +++ b/src/main/java/net/quickwrite/fluent4j/ast/placeable/base/FluentArgumentResult.java @@ -1,9 +1,8 @@ package net.quickwrite.fluent4j.ast.placeable.base; import net.quickwrite.fluent4j.ast.FluentElement; -import net.quickwrite.fluent4j.util.args.FluentArgs; -import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; public interface FluentArgumentResult { - FluentElement getArgumentResult(final DirectFluentBundle bundle, final FluentArgs arguments); + FluentElement getArgumentResult(AccessorBundle bundle); } diff --git a/src/main/java/net/quickwrite/fluent4j/ast/placeable/base/FluentFunction.java b/src/main/java/net/quickwrite/fluent4j/ast/placeable/base/FluentFunction.java index 9b1b15c9..6add2080 100644 --- a/src/main/java/net/quickwrite/fluent4j/ast/placeable/base/FluentFunction.java +++ b/src/main/java/net/quickwrite/fluent4j/ast/placeable/base/FluentFunction.java @@ -4,8 +4,8 @@ import net.quickwrite.fluent4j.exception.FluentParseException; import net.quickwrite.fluent4j.util.StringSlice; import net.quickwrite.fluent4j.util.args.FluentArgs; -import net.quickwrite.fluent4j.util.args.FunctionFluentArguments; import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; /** * Implements the basis for a value that gets @@ -34,13 +34,12 @@ public FluentFunction(final String functionName, final FluentArgs arguments) { * Returns the arguments that the function * has itself in a sanitized form. * - * @param bundle The bundle that this is being called from - * @param arguments The arguments in this scope + * @param bundle The arguments that are getting passed down * @return The sanitized arguments of the function */ - protected FluentArgs getArguments(final DirectFluentBundle bundle, final FluentArgs arguments) { + protected FluentArgs getArguments(final AccessorBundle bundle) { if (this.arguments != null) - this.arguments.sanitize(bundle, arguments); + this.arguments.sanitize(bundle); return this.arguments; } @@ -49,10 +48,9 @@ protected FluentArgs getArguments(final DirectFluentBundle bundle, final FluentA * Returns the {@link FluentElement} that the function is returning. * * @param bundle The bundle that this is being called from - * @param arguments The arguments that are passed into this function * @return The resulting {@link FluentElement} that has been created */ - public abstract FluentElement getArgumentResult(final DirectFluentBundle bundle, final FluentArgs arguments); + public abstract FluentElement getArgumentResult(final AccessorBundle bundle); /** * Checks if this FluentFunction and the selector are the same. diff --git a/src/main/java/net/quickwrite/fluent4j/functions/AbstractFunction.java b/src/main/java/net/quickwrite/fluent4j/functions/AbstractFunction.java index fd369596..77f72162 100644 --- a/src/main/java/net/quickwrite/fluent4j/functions/AbstractFunction.java +++ b/src/main/java/net/quickwrite/fluent4j/functions/AbstractFunction.java @@ -5,6 +5,7 @@ import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; import net.quickwrite.fluent4j.ast.placeable.base.FluentPlaceable; import net.quickwrite.fluent4j.ast.placeable.NumberLiteral; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; /** * Functions provide additional functionality available to the localizers. @@ -70,5 +71,5 @@ public String getIdentifier() { * @param arguments The arguments the function gets * @return The result */ - public abstract FluentPlaceable getResult(final DirectFluentBundle bundle, final FunctionFluentArgs arguments); + public abstract FluentPlaceable getResult(final AccessorBundle bundle, final FunctionFluentArgs arguments); } diff --git a/src/main/java/net/quickwrite/fluent4j/functions/NumberFunction.java b/src/main/java/net/quickwrite/fluent4j/functions/NumberFunction.java index 17d0cf1c..9ae4a0c6 100644 --- a/src/main/java/net/quickwrite/fluent4j/functions/NumberFunction.java +++ b/src/main/java/net/quickwrite/fluent4j/functions/NumberFunction.java @@ -3,10 +3,10 @@ import net.quickwrite.fluent4j.ast.FluentElement; import net.quickwrite.fluent4j.util.args.FluentArgs; import net.quickwrite.fluent4j.util.args.FunctionFluentArgs; -import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; import net.quickwrite.fluent4j.ast.placeable.NumberLiteral; import net.quickwrite.fluent4j.ast.placeable.base.FluentPlaceable; import net.quickwrite.fluent4j.util.args.CustomNumberLiteral; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; import java.text.ParseException; @@ -74,7 +74,7 @@ public NumberFunction() { * @return The number as a {@link CustomNumberLiteral} with the parameters */ @Override - public FluentPlaceable getResult(final DirectFluentBundle bundle, final FunctionFluentArgs arguments) { + public FluentPlaceable getResult(final AccessorBundle bundle, final FunctionFluentArgs arguments) { final FluentElement number = arguments.getPositional(0); CustomNumberLiteral numberLiteral; diff --git a/src/main/java/net/quickwrite/fluent4j/util/args/CustomNumberLiteral.java b/src/main/java/net/quickwrite/fluent4j/util/args/CustomNumberLiteral.java index 78cd80a4..f174fca9 100644 --- a/src/main/java/net/quickwrite/fluent4j/util/args/CustomNumberLiteral.java +++ b/src/main/java/net/quickwrite/fluent4j/util/args/CustomNumberLiteral.java @@ -1,8 +1,8 @@ package net.quickwrite.fluent4j.util.args; import com.ibm.icu.text.NumberFormat; -import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; import net.quickwrite.fluent4j.ast.placeable.NumberLiteral; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; import java.math.BigDecimal; import java.text.ParseException; @@ -46,8 +46,8 @@ public void setUseGrouping(boolean useGrouping) { } @Override - public String getResult(final DirectFluentBundle bundle, final FluentArgs arguments) { - NumberFormat numberFormat = NumberFormat.getInstance(bundle.getLocale()); + public String getResult(final AccessorBundle bundle) { + NumberFormat numberFormat = NumberFormat.getInstance(bundle.getBundle().getLocale()); numberFormat.setGroupingUsed(useGrouping); numberFormat.setMaximumFractionDigits(maximumFractionDigits); numberFormat.setMinimumFractionDigits(minimumFractionDigits); diff --git a/src/main/java/net/quickwrite/fluent4j/util/args/FluentArgs.java b/src/main/java/net/quickwrite/fluent4j/util/args/FluentArgs.java index c24ae1ba..6e3a9b88 100644 --- a/src/main/java/net/quickwrite/fluent4j/util/args/FluentArgs.java +++ b/src/main/java/net/quickwrite/fluent4j/util/args/FluentArgs.java @@ -1,7 +1,7 @@ package net.quickwrite.fluent4j.util.args; import net.quickwrite.fluent4j.ast.FluentElement; -import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; import java.util.Set; @@ -20,11 +20,10 @@ public interface FluentArgs { *

* This is necessary if the scopes are getting changed as a new scope does not have access * every variable the previous scope had. + * @param bundle The main bundle * - * @param bundle The main bundle - * @param arguments The old arguments */ - void sanitize(final DirectFluentBundle bundle, final FluentArgs arguments); + void sanitize(final AccessorBundle bundle); /** * Adds a new named argument to the named arguments. diff --git a/src/main/java/net/quickwrite/fluent4j/util/args/FluentArguments.java b/src/main/java/net/quickwrite/fluent4j/util/args/FluentArguments.java index d57af2dd..c79e9190 100644 --- a/src/main/java/net/quickwrite/fluent4j/util/args/FluentArguments.java +++ b/src/main/java/net/quickwrite/fluent4j/util/args/FluentArguments.java @@ -2,7 +2,7 @@ import net.quickwrite.fluent4j.ast.FluentElement; import net.quickwrite.fluent4j.ast.placeable.base.FluentArgumentResult; -import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; import java.util.HashMap; import java.util.Map; @@ -34,12 +34,12 @@ public FluentArguments(final Map namedArguments) { } @Override - public void sanitize(final DirectFluentBundle bundle, final FluentArgs arguments) { + public void sanitize(AccessorBundle bundle) { for (final String key : namedArguments.keySet()) { final FluentElement argument = namedArguments.get(key); if (argument instanceof FluentArgumentResult) { - namedArguments.put(key, ((FluentArgumentResult) argument).getArgumentResult(bundle, arguments)); + namedArguments.put(key, ((FluentArgumentResult) argument).getArgumentResult(bundle)); } } } diff --git a/src/main/java/net/quickwrite/fluent4j/util/args/FunctionFluentArguments.java b/src/main/java/net/quickwrite/fluent4j/util/args/FunctionFluentArguments.java index 7701cc9d..8a715a1d 100644 --- a/src/main/java/net/quickwrite/fluent4j/util/args/FunctionFluentArguments.java +++ b/src/main/java/net/quickwrite/fluent4j/util/args/FunctionFluentArguments.java @@ -1,8 +1,8 @@ package net.quickwrite.fluent4j.util.args; import net.quickwrite.fluent4j.ast.FluentElement; -import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; import net.quickwrite.fluent4j.ast.placeable.base.FluentArgumentResult; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; import java.util.*; @@ -36,12 +36,12 @@ public FunctionFluentArguments(final Map namedArguments, } @Override - public void sanitize(final DirectFluentBundle bundle, final FluentArgs arguments) { + public void sanitize(AccessorBundle bundle) { for (final String key : namedArguments.keySet()) { final FluentElement argument = namedArguments.get(key); if (argument instanceof FluentArgumentResult) { - namedArguments.put(key, ((FluentArgumentResult) argument).getArgumentResult(bundle, arguments)); + namedArguments.put(key, ((FluentArgumentResult) argument).getArgumentResult(bundle)); } } @@ -49,7 +49,7 @@ public void sanitize(final DirectFluentBundle bundle, final FluentArgs arguments final FluentElement argument = positionalArguments.get(i); if (argument instanceof FluentArgumentResult) { - positionalArguments.set(i, ((FluentArgumentResult) argument).getArgumentResult(bundle, arguments)); + positionalArguments.set(i, ((FluentArgumentResult) argument).getArgumentResult(bundle)); } } } diff --git a/src/main/java/net/quickwrite/fluent4j/util/bundle/DirectFluentBundle.java b/src/main/java/net/quickwrite/fluent4j/util/bundle/DirectFluentBundle.java index c7da8e66..0df6d49f 100644 --- a/src/main/java/net/quickwrite/fluent4j/util/bundle/DirectFluentBundle.java +++ b/src/main/java/net/quickwrite/fluent4j/util/bundle/DirectFluentBundle.java @@ -1,10 +1,7 @@ package net.quickwrite.fluent4j.util.bundle; -import com.ibm.icu.util.ULocale; import net.quickwrite.fluent4j.ast.FluentMessage; import net.quickwrite.fluent4j.ast.FluentTerm; -import net.quickwrite.fluent4j.functions.AbstractFunction; -import net.quickwrite.fluent4j.util.args.FluentArgs; public interface DirectFluentBundle extends FluentBundle { /** diff --git a/src/main/java/net/quickwrite/fluent4j/util/bundle/ResourceFluentBundle.java b/src/main/java/net/quickwrite/fluent4j/util/bundle/ResourceFluentBundle.java index c441530c..ee3f83e9 100644 --- a/src/main/java/net/quickwrite/fluent4j/util/bundle/ResourceFluentBundle.java +++ b/src/main/java/net/quickwrite/fluent4j/util/bundle/ResourceFluentBundle.java @@ -9,6 +9,7 @@ import net.quickwrite.fluent4j.functions.AbstractFunction; import net.quickwrite.fluent4j.util.BuiltinFunctions; import net.quickwrite.fluent4j.util.args.FluentArgs; +import net.quickwrite.fluent4j.util.bundle.args.AccessorElementsBundle; import java.util.*; @@ -111,7 +112,11 @@ public Optional getMessage(final String key, final FluentArgs arguments) return Optional.empty(); } - return Optional.of(message.getResult(this, arguments != null ? arguments : FluentArgs.EMPTY_ARGS).toString()); + return Optional.of( + message.getResult( + new AccessorElementsBundle(this, arguments != null ? arguments : FluentArgs.EMPTY_ARGS) + ).toString() + ); } @Override diff --git a/src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessorBundle.java b/src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessorBundle.java new file mode 100644 index 00000000..83d9f9dc --- /dev/null +++ b/src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessorBundle.java @@ -0,0 +1,10 @@ +package net.quickwrite.fluent4j.util.bundle.args; + +import net.quickwrite.fluent4j.util.args.FluentArgs; +import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; + +public interface AccessorBundle { + DirectFluentBundle getBundle(); + + FluentArgs getArguments(); +} diff --git a/src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessorElementsBundle.java b/src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessorElementsBundle.java new file mode 100644 index 00000000..2f031e94 --- /dev/null +++ b/src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessorElementsBundle.java @@ -0,0 +1,24 @@ +package net.quickwrite.fluent4j.util.bundle.args; + +import net.quickwrite.fluent4j.util.args.FluentArgs; +import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; + +public class AccessorElementsBundle implements AccessorBundle { + private final DirectFluentBundle bundle; + private final FluentArgs arguments; + + public AccessorElementsBundle(final DirectFluentBundle bundle, final FluentArgs arguments) { + this.bundle = bundle; + this.arguments = arguments; + } + + @Override + public DirectFluentBundle getBundle() { + return this.bundle; + } + + @Override + public FluentArgs getArguments() { + return this.arguments; + } +} diff --git a/src/test/java/net/quickwrite/fluent4j/TestCallExpressions.java b/src/test/java/net/quickwrite/fluent4j/TestCallExpressions.java index 31fb025c..d11e820d 100644 --- a/src/test/java/net/quickwrite/fluent4j/TestCallExpressions.java +++ b/src/test/java/net/quickwrite/fluent4j/TestCallExpressions.java @@ -6,6 +6,7 @@ import net.quickwrite.fluent4j.util.args.FunctionFluentArgs; import net.quickwrite.fluent4j.util.bundle.DirectFluentBundle; import net.quickwrite.fluent4j.util.bundle.FluentBundle; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; import org.junit.Before; import org.junit.Test; import org.junit.jupiter.api.Assertions; @@ -316,7 +317,7 @@ public FunFunction() { } @Override - public FluentPlaceable getResult(final DirectFluentBundle bundle, final FunctionFluentArgs arguments) { + public FluentPlaceable getResult(final AccessorBundle bundle, final FunctionFluentArgs arguments) { if (arguments.isEmpty()) { return new StringLiteral("{FUN(void)}"); } @@ -325,7 +326,7 @@ public FluentPlaceable getResult(final DirectFluentBundle bundle, final Function stringBuilder.append("[p:"); for (int i = 0; i < arguments.getPositionalSize(); i++) { - stringBuilder.append(arguments.getPositional(i).getResult(bundle, arguments)); + stringBuilder.append(arguments.getPositional(i).getResult(bundle)); stringBuilder.append(","); } @@ -334,7 +335,7 @@ public FluentPlaceable getResult(final DirectFluentBundle bundle, final Function for (final String key : arguments.getNamedKeys()) { stringBuilder.append(key); stringBuilder.append("."); - stringBuilder.append(arguments.getNamed(key).getResult(bundle, arguments)); + stringBuilder.append(arguments.getNamed(key).getResult(bundle)); stringBuilder.append(","); } From 678af98a61d1d3877c3abe56baaecc694e71995b Mon Sep 17 00:00:00 2001 From: QuickWrite <54590845+QuickWrite@users.noreply.github.com> Date: Thu, 13 Oct 2022 21:43:21 +0200 Subject: [PATCH 2/6] Fix: Multiple Calls of TermReferences If a TermReference is called multiple times and it contains the possibility of using variables it is getting stuck on the first variable that was passed down in the parameters. --- .../fluent4j/ast/placeable/TermReference.java | 2 +- .../ast/placeable/base/FluentFunction.java | 6 +-- .../fluent4j/util/args/FluentArgs.java | 2 +- .../fluent4j/util/args/FluentArguments.java | 19 ++++++-- .../util/args/FunctionFluentArguments.java | 43 ++++++++----------- 5 files changed, 37 insertions(+), 35 deletions(-) diff --git a/src/main/java/net/quickwrite/fluent4j/ast/placeable/TermReference.java b/src/main/java/net/quickwrite/fluent4j/ast/placeable/TermReference.java index 35acd2f5..90129f63 100644 --- a/src/main/java/net/quickwrite/fluent4j/ast/placeable/TermReference.java +++ b/src/main/java/net/quickwrite/fluent4j/ast/placeable/TermReference.java @@ -41,7 +41,7 @@ protected boolean check(final String string) { @Override public CharSequence getResult(final AccessorBundle bundle) { - return this.getArgumentResult(bundle).getResult(new AccessorElementsBundle(bundle.getBundle(), arguments)); + return this.getArgumentResult(bundle).getResult(new AccessorElementsBundle(bundle.getBundle(), this.getArguments(bundle))); } /** diff --git a/src/main/java/net/quickwrite/fluent4j/ast/placeable/base/FluentFunction.java b/src/main/java/net/quickwrite/fluent4j/ast/placeable/base/FluentFunction.java index 6add2080..d0b71d18 100644 --- a/src/main/java/net/quickwrite/fluent4j/ast/placeable/base/FluentFunction.java +++ b/src/main/java/net/quickwrite/fluent4j/ast/placeable/base/FluentFunction.java @@ -38,10 +38,10 @@ public FluentFunction(final String functionName, final FluentArgs arguments) { * @return The sanitized arguments of the function */ protected FluentArgs getArguments(final AccessorBundle bundle) { - if (this.arguments != null) - this.arguments.sanitize(bundle); + if (this.arguments == null) + return null; - return this.arguments; + return this.arguments.sanitize(bundle); } /** diff --git a/src/main/java/net/quickwrite/fluent4j/util/args/FluentArgs.java b/src/main/java/net/quickwrite/fluent4j/util/args/FluentArgs.java index 6e3a9b88..e3d22519 100644 --- a/src/main/java/net/quickwrite/fluent4j/util/args/FluentArgs.java +++ b/src/main/java/net/quickwrite/fluent4j/util/args/FluentArgs.java @@ -23,7 +23,7 @@ public interface FluentArgs { * @param bundle The main bundle * */ - void sanitize(final AccessorBundle bundle); + FluentArgs sanitize(final AccessorBundle bundle); /** * Adds a new named argument to the named arguments. diff --git a/src/main/java/net/quickwrite/fluent4j/util/args/FluentArguments.java b/src/main/java/net/quickwrite/fluent4j/util/args/FluentArguments.java index c79e9190..c3ef71bb 100644 --- a/src/main/java/net/quickwrite/fluent4j/util/args/FluentArguments.java +++ b/src/main/java/net/quickwrite/fluent4j/util/args/FluentArguments.java @@ -13,7 +13,7 @@ * positional arguments. */ public class FluentArguments implements FluentArgs { - private final Map namedArguments; + protected final Map namedArguments; /** * Creates a new argument container with the given @@ -34,14 +34,21 @@ public FluentArguments(final Map namedArguments) { } @Override - public void sanitize(AccessorBundle bundle) { + public FluentArgs sanitize(final AccessorBundle bundle) { + final FluentArgs args = new FluentArguments(); + for (final String key : namedArguments.keySet()) { final FluentElement argument = namedArguments.get(key); if (argument instanceof FluentArgumentResult) { - namedArguments.put(key, ((FluentArgumentResult) argument).getArgumentResult(bundle)); + args.setNamed(key, ((FluentArgumentResult) argument).getArgumentResult(bundle)); + continue; } + + args.setNamed(key, argument); } + + return args; } @Override @@ -64,9 +71,13 @@ public boolean isEmpty() { return this.namedArguments.isEmpty(); } + public FluentArgs clone() throws CloneNotSupportedException { + return (FluentArgs) super.clone(); + } + @Override public String toString() { - return "ResourceNamedFluentArguments: {\n" + + return "FluentArguments: {\n" + "\t\t\tnamedArguments: \"" + this.namedArguments + "\"\n" + "\t\t}"; } diff --git a/src/main/java/net/quickwrite/fluent4j/util/args/FunctionFluentArguments.java b/src/main/java/net/quickwrite/fluent4j/util/args/FunctionFluentArguments.java index 8a715a1d..f4973d6a 100644 --- a/src/main/java/net/quickwrite/fluent4j/util/args/FunctionFluentArguments.java +++ b/src/main/java/net/quickwrite/fluent4j/util/args/FunctionFluentArguments.java @@ -11,9 +11,8 @@ * are used as the parameters when a message, term or a function * is getting accessed. */ -public class FunctionFluentArguments implements FunctionFluentArgs { - private final Map namedArguments; - private final List positionalArguments; +public class FunctionFluentArguments extends FluentArguments implements FunctionFluentArgs { + protected final List positionalArguments; /** * Creates a new empty argument @@ -31,27 +30,34 @@ public FunctionFluentArguments() { * @param positionalArguments The positional arguments */ public FunctionFluentArguments(final Map namedArguments, final List positionalArguments) { - this.namedArguments = namedArguments; + super(namedArguments); this.positionalArguments = positionalArguments; } @Override - public void sanitize(AccessorBundle bundle) { + public FluentArgs sanitize(final AccessorBundle bundle) { + final FunctionFluentArgs args = new FunctionFluentArguments(); + for (final String key : namedArguments.keySet()) { final FluentElement argument = namedArguments.get(key); if (argument instanceof FluentArgumentResult) { - namedArguments.put(key, ((FluentArgumentResult) argument).getArgumentResult(bundle)); + args.setNamed(key, ((FluentArgumentResult) argument).getArgumentResult(bundle)); + continue; } - } - for (int i = 0; i < positionalArguments.size(); i++) { - final FluentElement argument = positionalArguments.get(i); + args.setNamed(key, argument); + } + for (final FluentElement argument : positionalArguments) { if (argument instanceof FluentArgumentResult) { - positionalArguments.set(i, ((FluentArgumentResult) argument).getArgumentResult(bundle)); + args.addPositional(((FluentArgumentResult) argument).getArgumentResult(bundle)); + continue; } + args.addPositional(argument); } + + return args; } @Override @@ -68,21 +74,6 @@ public int getPositionalSize() { return this.positionalArguments.size(); } - @Override - public void setNamed(final String key, final FluentElement argument) { - this.namedArguments.put(key, argument); - } - - @Override - public FluentElement getNamed(final String key) { - return this.namedArguments.get(key); - } - - @Override - public Set getNamedKeys() { - return this.namedArguments.keySet(); - } - @Override public void addPositional(final FluentElement argument) { this.positionalArguments.add(argument); @@ -95,7 +86,7 @@ public boolean isEmpty() { @Override public String toString() { - return "ResourceFluentArguments: {\n" + + return "FunctionFluentArguments: {\n" + "\t\t\tnamedArguments: \"" + this.namedArguments + "\"\n" + "\t\t\tpositionalArguments: \"" + this.positionalArguments + "\"\n" + "\t\t}"; From d6cd85ded401d76c5e16b52538b77f44a65f97b9 Mon Sep 17 00:00:00 2001 From: QuickWrite <54590845+QuickWrite@users.noreply.github.com> Date: Thu, 13 Oct 2022 22:04:31 +0200 Subject: [PATCH 3/6] Fix cyclic-reference problem --- .../ast/placeable/AttributeReference.java | 6 ++ .../ast/placeable/MessageReference.java | 4 +- .../fluent4j/ast/placeable/TermReference.java | 12 ++-- .../ast/placeable/VariableReference.java | 2 +- .../util/bundle/DirectFluentBundle.java | 40 ++++++++++++ .../util/bundle/ResourceFluentBundle.java | 62 +++++++++++++++---- .../util/bundle/args/AccessedStorage.java | 9 +++ .../bundle/args/AccessedStorageBundle.java | 24 +++++++ .../util/bundle/args/AccessorBundle.java | 2 + .../bundle/args/AccessorElementsBundle.java | 10 ++- 10 files changed, 146 insertions(+), 25 deletions(-) create mode 100644 src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessedStorage.java create mode 100644 src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessedStorageBundle.java diff --git a/src/main/java/net/quickwrite/fluent4j/ast/placeable/AttributeReference.java b/src/main/java/net/quickwrite/fluent4j/ast/placeable/AttributeReference.java index 3dd61ded..085eaee2 100644 --- a/src/main/java/net/quickwrite/fluent4j/ast/placeable/AttributeReference.java +++ b/src/main/java/net/quickwrite/fluent4j/ast/placeable/AttributeReference.java @@ -70,6 +70,12 @@ public FluentElement getArgumentResult(final AccessorBundle bundle) { return this; } + if (bundle.getAccessedStorage().alreadyAccessed(attribute)) { + return this; + } + + bundle.getAccessedStorage().addElement(attribute); + final List elementList = attribute.getElements(); if (elementList.size() != 1) { diff --git a/src/main/java/net/quickwrite/fluent4j/ast/placeable/MessageReference.java b/src/main/java/net/quickwrite/fluent4j/ast/placeable/MessageReference.java index 604959d6..a15e40ba 100644 --- a/src/main/java/net/quickwrite/fluent4j/ast/placeable/MessageReference.java +++ b/src/main/java/net/quickwrite/fluent4j/ast/placeable/MessageReference.java @@ -37,9 +37,9 @@ public String stringValue() { @Override public CharSequence getResult(final AccessorBundle bundle) { - return bundle + return bundle .getBundle() - .getMessage(this.stringValue(), bundle.getArguments()) + .getMessage(this.stringValue(), bundle) .orElse("{" + this.stringValue() + "}"); } diff --git a/src/main/java/net/quickwrite/fluent4j/ast/placeable/TermReference.java b/src/main/java/net/quickwrite/fluent4j/ast/placeable/TermReference.java index 90129f63..34dd8963 100644 --- a/src/main/java/net/quickwrite/fluent4j/ast/placeable/TermReference.java +++ b/src/main/java/net/quickwrite/fluent4j/ast/placeable/TermReference.java @@ -41,7 +41,9 @@ protected boolean check(final String string) { @Override public CharSequence getResult(final AccessorBundle bundle) { - return this.getArgumentResult(bundle).getResult(new AccessorElementsBundle(bundle.getBundle(), this.getArguments(bundle))); + return bundle.getBundle() + .getTerm(this.functionName, new AccessorElementsBundle(bundle.getBundle(), this.getArguments(bundle), bundle.getAccessedStorage())) + .orElse("{-" + this.functionName + "}"); } /** @@ -50,13 +52,7 @@ public CharSequence getResult(final AccessorBundle bundle) { */ @Override public FluentElement getArgumentResult(final AccessorBundle bundle) { - final FluentTerm term = bundle.getBundle().getTerm(this.functionName); - - if (term == null) { - return new StringLiteral("{-" + this.functionName + "}"); - } - - return term; + return new StringLiteral(getResult(bundle).toString()); } @Override diff --git a/src/main/java/net/quickwrite/fluent4j/ast/placeable/VariableReference.java b/src/main/java/net/quickwrite/fluent4j/ast/placeable/VariableReference.java index 4da95b1d..96f24fad 100644 --- a/src/main/java/net/quickwrite/fluent4j/ast/placeable/VariableReference.java +++ b/src/main/java/net/quickwrite/fluent4j/ast/placeable/VariableReference.java @@ -60,7 +60,7 @@ public FluentElement getArgumentResult(final AccessorBundle bundle) { return new StringLiteral("{$" + content + "}"); } - return arguments.getNamed(content); + return argument; } @Override diff --git a/src/main/java/net/quickwrite/fluent4j/util/bundle/DirectFluentBundle.java b/src/main/java/net/quickwrite/fluent4j/util/bundle/DirectFluentBundle.java index 0df6d49f..57751233 100644 --- a/src/main/java/net/quickwrite/fluent4j/util/bundle/DirectFluentBundle.java +++ b/src/main/java/net/quickwrite/fluent4j/util/bundle/DirectFluentBundle.java @@ -2,6 +2,9 @@ import net.quickwrite.fluent4j.ast.FluentMessage; import net.quickwrite.fluent4j.ast.FluentTerm; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; + +import java.util.Optional; public interface DirectFluentBundle extends FluentBundle { /** @@ -21,6 +24,24 @@ public interface DirectFluentBundle extends FluentBundle { */ FluentTerm getTerm(final String key); + /** + * Returns the {@link FluentTerm} that is being stored + * for the {@code key}. + * + *

+ * So when the {@code .ftl}-files contain: + *

+     *     -test = Hello World!
+     * 
+ * it would return the {@link FluentTerm} for the key + * {@code test} but {@code null} for anything else. + * + * @param bundle The bundle that is being used as an argument + * @param key The key that the {@link FluentTerm} is stored in. + * @return The term itself + */ + Optional getTerm(final String key, final AccessorBundle bundle); + /** * Returns the {@link FluentMessage} that is being stored * for the {@code key}. @@ -38,4 +59,23 @@ public interface DirectFluentBundle extends FluentBundle { * @return The message itself */ FluentMessage getMessage(final String key); + + /** + * Returns the {@link FluentMessage} that is being stored + * for the {@code key}. + * + *

+ * So when the {@code .ftl}-files contain: + *

+     *     test = Hello World!
+     * 
+ *

+ * it would return the {@link FluentMessage} for the key + * {@code test} but {@code null} for anything else. + * + * @param key The key that the {@link FluentMessage} is stored in. + * @param bundle The bundle that is being used as an argument + * @return The message itself + */ + Optional getMessage(final String key, final AccessorBundle bundle); } diff --git a/src/main/java/net/quickwrite/fluent4j/util/bundle/ResourceFluentBundle.java b/src/main/java/net/quickwrite/fluent4j/util/bundle/ResourceFluentBundle.java index ee3f83e9..4bff333a 100644 --- a/src/main/java/net/quickwrite/fluent4j/util/bundle/ResourceFluentBundle.java +++ b/src/main/java/net/quickwrite/fluent4j/util/bundle/ResourceFluentBundle.java @@ -9,6 +9,8 @@ import net.quickwrite.fluent4j.functions.AbstractFunction; import net.quickwrite.fluent4j.util.BuiltinFunctions; import net.quickwrite.fluent4j.util.args.FluentArgs; +import net.quickwrite.fluent4j.util.bundle.args.AccessedStorageBundle; +import net.quickwrite.fluent4j.util.bundle.args.AccessorBundle; import net.quickwrite.fluent4j.util.bundle.args.AccessorElementsBundle; import java.util.*; @@ -48,16 +50,6 @@ public ResourceFluentBundle(final ULocale locale, final FluentResource resource) this.addResource(resource); } - @Override - public FluentTerm getTerm(final String key) { - return this.terms.get(key); - } - - @Override - public FluentMessage getMessage(final String key) { - return this.messages.get(key); - } - @Override public void addResource(final FluentResource resource) { for (final FluentElement element : resource.getElements()) { @@ -106,16 +98,60 @@ public boolean hasMessage(final String key) { @Override public Optional getMessage(final String key, final FluentArgs arguments) { + return getMessage( + key, + new AccessorElementsBundle( + this, + arguments != null ? arguments : FluentArgs.EMPTY_ARGS, + new AccessedStorageBundle()) + ); + } + + @Override + public FluentTerm getTerm(final String key) { + return this.terms.get(key); + } + + @Override + public Optional getTerm(final String key, final AccessorBundle bundle) { + final FluentTerm term = this.getTerm(key); + + if (term == null) { + return Optional.empty(); + } + + if (bundle.getAccessedStorage().alreadyAccessed(term)) { + return Optional.empty(); + } + + bundle.getAccessedStorage().addElement(term); + + return Optional.of( + term.getResult(bundle).toString() + ); + } + + @Override + public FluentMessage getMessage(final String key) { + return this.messages.get(key); + } + + @Override + public Optional getMessage(final String key, final AccessorBundle bundle) { final FluentMessage message = this.getMessage(key); if (message == null) { return Optional.empty(); } + if (bundle.getAccessedStorage().alreadyAccessed(message)) { + return Optional.empty(); + } + + bundle.getAccessedStorage().addElement(message); + return Optional.of( - message.getResult( - new AccessorElementsBundle(this, arguments != null ? arguments : FluentArgs.EMPTY_ARGS) - ).toString() + message.getResult(bundle).toString() ); } diff --git a/src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessedStorage.java b/src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessedStorage.java new file mode 100644 index 00000000..84c756a4 --- /dev/null +++ b/src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessedStorage.java @@ -0,0 +1,9 @@ +package net.quickwrite.fluent4j.util.bundle.args; + +import net.quickwrite.fluent4j.ast.FluentBase; + +public interface AccessedStorage { + boolean alreadyAccessed(final FluentBase element); + + void addElement(final FluentBase element); +} diff --git a/src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessedStorageBundle.java b/src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessedStorageBundle.java new file mode 100644 index 00000000..9e091f6f --- /dev/null +++ b/src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessedStorageBundle.java @@ -0,0 +1,24 @@ +package net.quickwrite.fluent4j.util.bundle.args; + +import net.quickwrite.fluent4j.ast.FluentBase; + +import java.util.HashSet; +import java.util.Set; + +public class AccessedStorageBundle implements AccessedStorage { + private final Set elementSet; + + public AccessedStorageBundle() { + this.elementSet = new HashSet<>(); + } + + @Override + public boolean alreadyAccessed(final FluentBase element) { + return this.elementSet.contains(element); + } + + @Override + public void addElement(final FluentBase element) { + this.elementSet.add(element); + } +} diff --git a/src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessorBundle.java b/src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessorBundle.java index 83d9f9dc..728cafa8 100644 --- a/src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessorBundle.java +++ b/src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessorBundle.java @@ -7,4 +7,6 @@ public interface AccessorBundle { DirectFluentBundle getBundle(); FluentArgs getArguments(); + + AccessedStorage getAccessedStorage(); } diff --git a/src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessorElementsBundle.java b/src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessorElementsBundle.java index 2f031e94..cf3962d1 100644 --- a/src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessorElementsBundle.java +++ b/src/main/java/net/quickwrite/fluent4j/util/bundle/args/AccessorElementsBundle.java @@ -6,10 +6,13 @@ public class AccessorElementsBundle implements AccessorBundle { private final DirectFluentBundle bundle; private final FluentArgs arguments; + private final AccessedStorage accessedStorage; - public AccessorElementsBundle(final DirectFluentBundle bundle, final FluentArgs arguments) { + public AccessorElementsBundle(final DirectFluentBundle bundle, final FluentArgs arguments, final AccessedStorage accessedStorage) { this.bundle = bundle; this.arguments = arguments; + + this.accessedStorage = accessedStorage; } @Override @@ -21,4 +24,9 @@ public DirectFluentBundle getBundle() { public FluentArgs getArguments() { return this.arguments; } + + @Override + public AccessedStorage getAccessedStorage() { + return this.accessedStorage; + } } From 5da2be1ff48864dea0fc04eb8d1310db898d393f Mon Sep 17 00:00:00 2001 From: QuickWrite <54590845+QuickWrite@users.noreply.github.com> Date: Sat, 15 Oct 2022 12:13:53 +0200 Subject: [PATCH 4/6] Add some tests --- .../quickwrite/fluent4j/TestRecursion.java | 27 +++++++++++ .../net/quickwrite/fluent4j/TestScopes.java | 46 +++++++++++++++++++ src/test/resources/input/recursion.ftl | 7 +++ src/test/resources/input/scopes.ftl | 21 +++++++++ 4 files changed, 101 insertions(+) create mode 100644 src/test/java/net/quickwrite/fluent4j/TestRecursion.java create mode 100644 src/test/java/net/quickwrite/fluent4j/TestScopes.java create mode 100644 src/test/resources/input/recursion.ftl create mode 100644 src/test/resources/input/scopes.ftl diff --git a/src/test/java/net/quickwrite/fluent4j/TestRecursion.java b/src/test/java/net/quickwrite/fluent4j/TestRecursion.java new file mode 100644 index 00000000..2c7e5863 --- /dev/null +++ b/src/test/java/net/quickwrite/fluent4j/TestRecursion.java @@ -0,0 +1,27 @@ +package net.quickwrite.fluent4j; + +import net.quickwrite.fluent4j.util.bundle.FluentBundle; +import org.junit.Before; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import java.io.IOException; + +public class TestRecursion { + private FluentBundle bundle; + + @Before + public void setUp() throws IOException { + this.bundle = GetFileHelper.getFluentBundle("recursion.ftl"); + } + + @Test + public void testRecursiveKey01() { + Assertions.assertEquals("{recursive-key01}", GetFileHelper.getMessage(bundle, "recursive-key01")); + } + + @Test + public void testRecursiveTerm01() { + Assertions.assertEquals("{recursive-term01}", GetFileHelper.getMessage(bundle, "recursive-term01")); + } +} diff --git a/src/test/java/net/quickwrite/fluent4j/TestScopes.java b/src/test/java/net/quickwrite/fluent4j/TestScopes.java new file mode 100644 index 00000000..a5571d1c --- /dev/null +++ b/src/test/java/net/quickwrite/fluent4j/TestScopes.java @@ -0,0 +1,46 @@ +package net.quickwrite.fluent4j; + +import net.quickwrite.fluent4j.builder.FluentArgsBuilder; +import net.quickwrite.fluent4j.util.args.FluentArgs; +import net.quickwrite.fluent4j.util.bundle.FluentBundle; +import org.junit.Before; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import java.io.IOException; + +public class TestScopes { + private FluentBundle bundle; + private FluentArgs args; + + @Before + public void setUp() throws IOException { + this.bundle = GetFileHelper.getFluentBundle("scopes.ftl"); + this.args = new FluentArgsBuilder().set("var1", "Hello").set("var2", "World").build(); + } + + @Test + public void testTopScope() { + Assertions.assertEquals("Hello World", bundle.getMessage("top-scope", args).orElseThrow()); + } + + @Test + public void testMessageScope1() { + Assertions.assertEquals("Hello World", bundle.getMessage("message-scope1", args).orElseThrow()); + } + + @Test + public void testMessageScope2() { + Assertions.assertEquals("Hello World", bundle.getMessage("message-scope2", args).orElseThrow()); + } + + @Test + public void testTermScope1() { + Assertions.assertEquals("{$var1} {$var2}", bundle.getMessage("term-scope1", args).orElseThrow()); + } + + @Test + public void testTermScope2() { + Assertions.assertEquals("Hello World", bundle.getMessage("term-scope2", args).orElseThrow()); + } +} diff --git a/src/test/resources/input/recursion.ftl b/src/test/resources/input/recursion.ftl new file mode 100644 index 00000000..71ce2c0b --- /dev/null +++ b/src/test/resources/input/recursion.ftl @@ -0,0 +1,7 @@ +# Tests if the program crashes if something +# is recursive + +recursive-key01 = { recursive-key01 } + +recursive-term01 = {-recursive-term01} +-recursive-term01 = {-recursive-term01} \ No newline at end of file diff --git a/src/test/resources/input/scopes.ftl b/src/test/resources/input/scopes.ftl new file mode 100644 index 00000000..39593fdd --- /dev/null +++ b/src/test/resources/input/scopes.ftl @@ -0,0 +1,21 @@ +# Different ways of using scopes + +## The scope that is being used with the arguments +top-scope = { $var1 } { $var2 } + +## The scope shouldn't change at all +message-scope1 = { int-message-scope1 } +int-message-scope1 = { $var1 } { $var2 } + +message-scope2 = { int-message-scope2 } +int-message-scope2 = { int-message-scope1 } + +## The scope should change to a scope without +## any values. +term-scope1 = { -int-term-scope1 } +-int-term-scope1 = { $var1 } { $var2 } + +## The scope should change to a scope with +## the same variable names and values +term-scope2 = { -int-term-scope2(var1: $var1, var2: $var2) } +-int-term-scope2 = { $var1 } { $var2 } From 90e0122f48eab30e3226e7af85a43a85407ae76b Mon Sep 17 00:00:00 2001 From: QuickWrite <54590845+QuickWrite@users.noreply.github.com> Date: Sat, 15 Oct 2022 12:14:32 +0200 Subject: [PATCH 5/6] Fix recursive test --- src/test/java/net/quickwrite/fluent4j/TestRecursion.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/net/quickwrite/fluent4j/TestRecursion.java b/src/test/java/net/quickwrite/fluent4j/TestRecursion.java index 2c7e5863..4562bcee 100644 --- a/src/test/java/net/quickwrite/fluent4j/TestRecursion.java +++ b/src/test/java/net/quickwrite/fluent4j/TestRecursion.java @@ -22,6 +22,6 @@ public void testRecursiveKey01() { @Test public void testRecursiveTerm01() { - Assertions.assertEquals("{recursive-term01}", GetFileHelper.getMessage(bundle, "recursive-term01")); + Assertions.assertEquals("{-recursive-term01}", GetFileHelper.getMessage(bundle, "recursive-term01")); } } From a439d6423e3908f8cee4af6b66f743d068e8b36d Mon Sep 17 00:00:00 2001 From: QuickWrite <54590845+QuickWrite@users.noreply.github.com> Date: Sun, 16 Oct 2022 17:13:06 +0200 Subject: [PATCH 6/6] Change the Version Change the version from 0.2.1-alpha to 0.2.2-alpha --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 77de9bed..330c9d25 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ net.quickwrite fluent4j - 0.2.1-alpha + 0.2.2-alpha