diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/analysis/CoverageChecker.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/analysis/CoverageChecker.java index a5075d5938c..17c9684ef47 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/analysis/CoverageChecker.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/analysis/CoverageChecker.java @@ -27,9 +27,9 @@ import software.amazon.smithy.rulesengine.language.EndpointRuleset; import software.amazon.smithy.rulesengine.language.eval.RuleEvaluator; import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.Identifier; -import software.amazon.smithy.rulesengine.language.lang.rule.Condition; -import software.amazon.smithy.rulesengine.language.lang.rule.Rule; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.rule.Condition; +import software.amazon.smithy.rulesengine.language.syntax.rule.Rule; import software.amazon.smithy.rulesengine.language.util.PathFinder; import software.amazon.smithy.rulesengine.language.util.StringUtils; import software.amazon.smithy.rulesengine.language.visit.TraversingVisitor; diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/Endpoint.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/Endpoint.java index f81cef72c90..49aa2b14924 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/Endpoint.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/Endpoint.java @@ -33,9 +33,11 @@ import software.amazon.smithy.rulesengine.language.eval.Scope; import software.amazon.smithy.rulesengine.language.eval.Type; import software.amazon.smithy.rulesengine.language.eval.Typecheck; -import software.amazon.smithy.rulesengine.language.lang.Identifier; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.lang.expr.Literal; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.expr.Literal; +import software.amazon.smithy.rulesengine.language.util.MandatorySourceLocation; +import software.amazon.smithy.rulesengine.language.util.SourceLocationTrackingBuilder; import software.amazon.smithy.rulesengine.language.util.StringUtils; import software.amazon.smithy.utils.BuilderRef; import software.amazon.smithy.utils.MapUtils; @@ -48,7 +50,7 @@ * An Endpoint as returned by EndpointRules. */ @SmithyUnstableApi -public final class Endpoint implements ToSmithyBuilder, FromSourceLocation, Typecheck, ToNode { +public final class Endpoint extends MandatorySourceLocation implements ToSmithyBuilder, Typecheck, ToNode { private static final String URL = "url"; private static final String PROPERTIES = "properties"; private static final String HEADERS = "headers"; @@ -59,9 +61,9 @@ public final class Endpoint implements ToSmithyBuilder, FromSourceLoca private final Expr url; private final Map> headers; private final Map properties; - private final SourceLocation sourceLocation; private Endpoint(Builder builder) { + super(builder.getSourceLocation()); this.url = SmithyBuilder.requiredState("url", builder.url); Map properties = new LinkedHashMap<>(builder.properties.copy()); List authSchemes = @@ -80,7 +82,6 @@ private Endpoint(Builder builder) { this.properties = properties; this.headers = builder.headers.copy(); - this.sourceLocation = SmithyBuilder.requiredState("sourceLocation", builder.getSourceLocation()); } public static Endpoint fromNode(Node node) { @@ -125,18 +126,13 @@ public static Builder builder() { return new Builder(SourceLocation.none()); } - @Override - public SourceLocation getSourceLocation() { - return sourceLocation; - } - public Expr getUrl() { return url; } @Override public Builder toBuilder() { - return builder(this.sourceLocation).url(url).properties(properties); + return builder(this.getSourceLocation()).url(url).properties(properties); } @Override @@ -233,7 +229,7 @@ public Map> getHeaders() { /** * Builder for {@link Endpoint}. */ - public static class Builder extends SourceAwareBuilder { + public static class Builder extends SourceLocationTrackingBuilder { private static final String SIGNING_NAME = "signingName"; private static final String SIGNING_REGION_SET = "signingRegionSet"; diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/EndpointRuleset.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/EndpointRuleset.java index 0b6c90baa47..f5616defb91 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/EndpointRuleset.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/EndpointRuleset.java @@ -32,9 +32,11 @@ import software.amazon.smithy.rulesengine.language.eval.Scope; import software.amazon.smithy.rulesengine.language.eval.Type; import software.amazon.smithy.rulesengine.language.eval.Typecheck; -import software.amazon.smithy.rulesengine.language.lang.parameters.Parameters; -import software.amazon.smithy.rulesengine.language.lang.rule.EndpointRule; -import software.amazon.smithy.rulesengine.language.lang.rule.Rule; +import software.amazon.smithy.rulesengine.language.syntax.parameters.Parameters; +import software.amazon.smithy.rulesengine.language.syntax.rule.EndpointRule; +import software.amazon.smithy.rulesengine.language.syntax.rule.Rule; +import software.amazon.smithy.rulesengine.language.util.MandatorySourceLocation; +import software.amazon.smithy.rulesengine.language.util.SourceLocationTrackingBuilder; import software.amazon.smithy.utils.BuilderRef; import software.amazon.smithy.utils.SmithyBuilder; import software.amazon.smithy.utils.SmithyUnstableApi; @@ -43,7 +45,7 @@ * A set of EndpointRules. Endpoint Rules describe the endpoint resolution behavior for a service. */ @SmithyUnstableApi -public final class EndpointRuleset implements FromSourceLocation, Typecheck, ToNode { +public final class EndpointRuleset extends MandatorySourceLocation implements Typecheck, ToNode { private static final String LATEST_VERSION = "1.3"; private static final String VERSION = "version"; private static final String PARAMETERS = "parameters"; @@ -53,13 +55,11 @@ public final class EndpointRuleset implements FromSourceLocation, Typecheck, ToN private final Parameters parameters; private final String version; - private final SourceLocation sourceLocation; - private EndpointRuleset(Builder builder) { + super(builder.getSourceLocation()); rules = builder.rules.copy(); parameters = SmithyBuilder.requiredState("parameters", builder.parameters); version = SmithyBuilder.requiredState("version", builder.version); - sourceLocation = builder.getSourceLocation(); } public static EndpointRuleset fromNode(Node node) throws RuleError { @@ -91,11 +91,6 @@ public List getRules() { return rules; } - @Override - public SourceLocation getSourceLocation() { - return sourceLocation; - } - @Override public Type typecheck(Scope scope) { return scope.inScope(() -> { @@ -122,7 +117,7 @@ public Node toNode() { public Builder toBuilder() { return builder() - .sourceLocation(sourceLocation) + .sourceLocation(getSourceLocation()) .parameters(parameters) .rules(getRules()); } @@ -160,7 +155,7 @@ public String toString() { return builder.toString(); } - public static class Builder extends SourceAwareBuilder { + public static class Builder extends SourceLocationTrackingBuilder { private final BuilderRef> rules = BuilderRef.forList(); private Parameters parameters; // default the version to the latest. diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/SourceAwareBuilder.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/SourceAwareBuilder.java deleted file mode 100644 index 6ef47195c54..00000000000 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/SourceAwareBuilder.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package software.amazon.smithy.rulesengine.language; - -import software.amazon.smithy.model.FromSourceLocation; -import software.amazon.smithy.model.SourceLocation; -import software.amazon.smithy.utils.SmithyBuilder; -import software.amazon.smithy.utils.SmithyUnstableApi; - -@SmithyUnstableApi -public abstract class SourceAwareBuilder, T> - implements SmithyBuilder, FromSourceLocation { - - protected SourceLocation sourceLocation; - - public SourceAwareBuilder(FromSourceLocation sourceLocation) { - if (sourceLocation.getSourceLocation() == SourceLocation.NONE) { - this.sourceLocation = javaLocation(); - } else { - this.sourceLocation = sourceLocation.getSourceLocation(); - } - } - - public static SourceLocation javaLocation() { - for (StackTraceElement e : Thread.currentThread().getStackTrace()) { - if (isStackTraceRelevant(e)) { - if (e.getFileName() == null) { - return SourceLocation.none(); - } - return new SourceLocation(e.getFileName(), e.getLineNumber(), 0); - } - } - return SourceLocation.none(); - } - - /** - * Tests if the given {@code StackTraceElement} is relevant for a comment - * used when writing debug information before calls to write. - * - *

The default implementation filters out all methods in "java.*", - * AbstractCodeWriter, software.amazon.smithy.utils.SymbolWriter, - * SimpleCodeWriter, and methods of the implementing subclass of - * AbstractCodeWriter. This method can be overridden to further filter - * stack frames as needed. - * - * @param e StackTraceElement to test. - * @return Returns true if this element should be in a comment. - */ - static boolean isStackTraceRelevant(StackTraceElement e) { - String normalized = e.getClassName().replace("$", "."); - return !normalized.startsWith("java.") - && !normalized.startsWith("jdk.") - // Ignore writes made by AbstractCodeWriter or AbstractCodeWriter$State. - && !normalized.startsWith(SourceAwareBuilder.class.getCanonicalName()) - //&& !normalized.startsWith(getClass().getCanonicalName()) - && !normalized.startsWith("software.amazon.smithy.rulesengine"); - } - - @Override - public SourceLocation getSourceLocation() { - return sourceLocation; - } - - @SuppressWarnings("unchecked") - public B sourceLocation(SourceLocation sourceLocation) { - this.sourceLocation = sourceLocation; - return (B) this; - } - -} diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/error/InvalidRulesException.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/error/InvalidRulesException.java new file mode 100644 index 00000000000..e9a9d3786cf --- /dev/null +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/error/InvalidRulesException.java @@ -0,0 +1,48 @@ +/* + * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.smithy.rulesengine.language.error; + +import software.amazon.smithy.model.FromSourceLocation; +import software.amazon.smithy.model.SourceLocation; +import software.amazon.smithy.rulesengine.language.util.SourceLocationHelpers; +import software.amazon.smithy.utils.SmithyUnstableApi; + +/** + * Exception thrown when the ruleset is invalid. + */ +@SmithyUnstableApi +public final class InvalidRulesException extends RuntimeException implements FromSourceLocation { + private final transient SourceLocation sourceLocation; + + public InvalidRulesException(String message, FromSourceLocation location) { + super(createMessage(message, location.getSourceLocation())); + sourceLocation = location.getSourceLocation(); + } + + @Override + public SourceLocation getSourceLocation() { + return sourceLocation; + } + + private static String createMessage(String message, SourceLocation sourceLocation) { + if (sourceLocation == SourceLocation.NONE) { + return message; + } else { + String prettyLocation = SourceLocationHelpers.stackTraceForm(sourceLocation); + return message.contains(prettyLocation) ? message : message + " (" + prettyLocation + ")"; + } + } +} diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/Eval.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/Eval.java deleted file mode 100644 index 801cc320cad..00000000000 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/Eval.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package software.amazon.smithy.rulesengine.language.eval; - -import software.amazon.smithy.utils.SmithyUnstableApi; - -@SmithyUnstableApi -public interface Eval { - Value eval(Scope scope); -} diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/RuleEngine.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/RuleEngine.java index 092743abf69..c7293c5e0c5 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/RuleEngine.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/RuleEngine.java @@ -17,7 +17,7 @@ import java.util.Map; import software.amazon.smithy.rulesengine.language.EndpointRuleset; -import software.amazon.smithy.rulesengine.language.lang.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; import software.amazon.smithy.utils.SmithyUnstableApi; @SmithyUnstableApi diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/RuleEvaluator.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/RuleEvaluator.java index 6b6ef7b3fb8..e6ac9e87d5b 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/RuleEvaluator.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/RuleEvaluator.java @@ -17,33 +17,23 @@ import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import software.amazon.smithy.rulesengine.language.Endpoint; import software.amazon.smithy.rulesengine.language.EndpointRuleset; -import software.amazon.smithy.rulesengine.language.lang.Identifier; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.lang.expr.Literal; -import software.amazon.smithy.rulesengine.language.lang.expr.Ref; -import software.amazon.smithy.rulesengine.language.lang.fn.BooleanEquals; -import software.amazon.smithy.rulesengine.language.lang.fn.Fn; -import software.amazon.smithy.rulesengine.language.lang.fn.GetAttr; -import software.amazon.smithy.rulesengine.language.lang.fn.IsSet; -import software.amazon.smithy.rulesengine.language.lang.fn.IsValidHostLabel; -import software.amazon.smithy.rulesengine.language.lang.fn.Not; -import software.amazon.smithy.rulesengine.language.lang.fn.ParseArn; -import software.amazon.smithy.rulesengine.language.lang.fn.ParseUrl; -import software.amazon.smithy.rulesengine.language.lang.fn.PartitionFn; -import software.amazon.smithy.rulesengine.language.lang.fn.StringEquals; -import software.amazon.smithy.rulesengine.language.lang.fn.Substring; -import software.amazon.smithy.rulesengine.language.lang.fn.UriEncode; -import software.amazon.smithy.rulesengine.language.lang.rule.Condition; -import software.amazon.smithy.rulesengine.language.lang.rule.Rule; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.expr.Literal; +import software.amazon.smithy.rulesengine.language.syntax.expr.Ref; +import software.amazon.smithy.rulesengine.language.syntax.fn.FunctionDefinition; +import software.amazon.smithy.rulesengine.language.syntax.fn.GetAttr; +import software.amazon.smithy.rulesengine.language.syntax.rule.Condition; +import software.amazon.smithy.rulesengine.language.syntax.rule.Rule; import software.amazon.smithy.rulesengine.language.visit.ExprVisitor; -import software.amazon.smithy.rulesengine.language.visit.FnVisitor; import software.amazon.smithy.rulesengine.language.visit.RuleValueVisitor; import software.amazon.smithy.utils.SmithyUnstableApi; @SmithyUnstableApi -public class RuleEvaluator implements FnVisitor, ExprVisitor { +public class RuleEvaluator implements ExprVisitor { private final Scope scope = new Scope<>(); public Value evaluateRuleset(EndpointRuleset ruleset, Map input) { @@ -69,75 +59,43 @@ public Value evaluateRuleset(EndpointRuleset ruleset, Map inp @Override public Value visitLiteral(Literal literal) { - return literal.eval(scope); + return literal.eval(this); } @Override public Value visitRef(Ref ref) { return scope .getValue(ref.getName()) - .orElseThrow( - () -> new RuntimeException(String.format("Invalid ruleset: %s was not in scope", ref))); + .orElse(Value.none()); } @Override - public Value visitFn(Fn fn) { - return fn.acceptFnVisitor(this); + public Value visitIsSet(Expr fn) { + return Value.bool(!fn.accept(this).isNone()); } @Override - public Value visitPartition(PartitionFn fn) { - return fn.eval(scope); + public Value visitNot(Expr not) { + return Value.bool(!not.accept(this).expectBool()); } @Override - public Value visitParseArn(ParseArn fn) { - return fn.eval(scope); + public Value visitBoolEquals(Expr left, Expr right) { + return Value.bool(left.accept(this).expectBool() == right.accept(this).expectBool()); } @Override - public Value visitIsValidHostLabel(IsValidHostLabel fn) { - return fn.eval(scope); + public Value visitStringEquals(Expr left, Expr right) { + return Value.bool(left.accept(this).expectString().equals(right.accept(this).expectString())); } - @Override - public Value visitBoolEquals(BooleanEquals fn) { - return fn.eval(scope); - } - - @Override - public Value visitStringEquals(StringEquals fn) { - return fn.eval(scope); - } - - @Override - public Value visitIsSet(IsSet fn) { - return fn.eval(scope); - } - - @Override - public Value visitNot(Not not) { - return Value.bool(!not.target().accept(this).expectBool()); - } - - @Override public Value visitGetAttr(GetAttr getAttr) { - return getAttr.eval(scope); - } - - @Override - public Value visitParseUrl(ParseUrl parseUrl) { - return parseUrl.eval(scope); - } - - @Override - public Value visitSubstring(Substring fn) { - return fn.eval(scope); + return getAttr.eval(getAttr.getTarget().accept(this)); } @Override - public Value visitUriEncode(UriEncode fn) { - return fn.eval(scope); + public Value visitLibraryFunction(FunctionDefinition defn, List args) { + return defn.eval(args.stream().map(arg -> arg.accept(this)).collect(Collectors.toList())); } private Value handleRule(Rule rule) { diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/Scope.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/Scope.java index 126567f4acb..c3817df493b 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/Scope.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/Scope.java @@ -25,8 +25,8 @@ import software.amazon.smithy.model.node.Node; import software.amazon.smithy.model.node.ObjectNode; import software.amazon.smithy.rulesengine.language.error.InnerParseError; -import software.amazon.smithy.rulesengine.language.lang.Identifier; -import software.amazon.smithy.rulesengine.language.lang.expr.Ref; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.expr.Ref; import software.amazon.smithy.utils.SmithyUnstableApi; @SmithyUnstableApi diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/ScopeLayer.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/ScopeLayer.java index 5c6f4b02e9f..07a0760b9a4 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/ScopeLayer.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/ScopeLayer.java @@ -20,8 +20,8 @@ import java.util.Map; import java.util.Objects; import java.util.Set; -import software.amazon.smithy.rulesengine.language.lang.Identifier; -import software.amazon.smithy.rulesengine.language.lang.expr.Ref; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.expr.Ref; import software.amazon.smithy.utils.SmithyUnstableApi; @SmithyUnstableApi diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/TestEvaluator.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/TestEvaluator.java index 6e2851d6011..b61b794a6a9 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/TestEvaluator.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/TestEvaluator.java @@ -22,7 +22,7 @@ import java.util.Map; import java.util.Optional; import software.amazon.smithy.rulesengine.language.EndpointRuleset; -import software.amazon.smithy.rulesengine.language.lang.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; import software.amazon.smithy.rulesengine.traits.EndpointTestCase; import software.amazon.smithy.rulesengine.traits.EndpointTestExpectation; import software.amazon.smithy.rulesengine.traits.ExpectedEndpoint; diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/Type.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/Type.java index 166207f0deb..367de57dc3f 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/Type.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/Type.java @@ -20,7 +20,7 @@ import java.util.Objects; import java.util.Optional; import software.amazon.smithy.rulesengine.language.error.InnerParseError; -import software.amazon.smithy.rulesengine.language.lang.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; import software.amazon.smithy.utils.SmithyUnstableApi; @SmithyUnstableApi diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/Value.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/Value.java index f01324e8385..350c0006e79 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/Value.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/eval/Value.java @@ -38,8 +38,9 @@ import software.amazon.smithy.model.node.ObjectNode; import software.amazon.smithy.model.node.StringNode; import software.amazon.smithy.model.node.ToNode; -import software.amazon.smithy.rulesengine.language.SourceAwareBuilder; -import software.amazon.smithy.rulesengine.language.lang.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.util.SourceLocationHelpers; +import software.amazon.smithy.rulesengine.language.util.SourceLocationTrackingBuilder; import software.amazon.smithy.utils.BuilderRef; import software.amazon.smithy.utils.SmithyBuilder; import software.amazon.smithy.utils.SmithyUnstableApi; @@ -481,7 +482,7 @@ public static Endpoint fromNode(Node node) { } public static Builder builder() { - return new Builder(SourceAwareBuilder.javaLocation()); + return new Builder(SourceLocationHelpers.javaLocation()); } @Override @@ -566,7 +567,7 @@ public String toString() { return sb.toString(); } - public static final class Builder extends SourceAwareBuilder { + public static final class Builder extends SourceLocationTrackingBuilder { private final BuilderRef> properties = BuilderRef.forOrderedMap(); private final BuilderRef>> headers = BuilderRef.forOrderedMap(); private String url; diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/impl/Arn.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/impl/Arn.java index 785aa9f5001..adcdeb126be 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/impl/Arn.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/impl/Arn.java @@ -16,7 +16,6 @@ package software.amazon.smithy.rulesengine.language.impl; import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -37,14 +36,6 @@ public final class Arn implements ToSmithyBuilder { private final String accountId; private final List resource; - public Arn(String partition, String service, String region, String accountId, List resource) { - this.partition = partition; - this.service = service; - this.region = region; - this.accountId = accountId; - this.resource = Collections.unmodifiableList(resource); - } - private Arn(Builder builder) { this.partition = SmithyBuilder.requiredState("partition", builder.partition); this.service = SmithyBuilder.requiredState("service", builder.service); diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/BooleanEquals.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/BooleanEquals.java deleted file mode 100644 index 55515aedbed..00000000000 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/BooleanEquals.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package software.amazon.smithy.rulesengine.language.lang.fn; - -import static software.amazon.smithy.rulesengine.language.error.RuleError.ctx; - -import software.amazon.smithy.rulesengine.language.eval.Scope; -import software.amazon.smithy.rulesengine.language.eval.Type; -import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.lang.parameters.Parameter; -import software.amazon.smithy.rulesengine.language.visit.FnVisitor; -import software.amazon.smithy.utils.Pair; -import software.amazon.smithy.utils.SmithyUnstableApi; - -@SmithyUnstableApi -public final class BooleanEquals extends Fn { - public static final String ID = "booleanEquals"; - - public BooleanEquals(FnNode fnNode) { - super(fnNode); - } - - public static BooleanEquals ofExprs(Expr left, Expr right) { - return new BooleanEquals(FnNode.ofExprs(ID, left, right)); - } - - public static BooleanEquals fromParam(Parameter param, Expr value) { - return BooleanEquals.ofExprs(param.expr(), value); - } - - @Override - public T acceptFnVisitor(FnVisitor visitor) { - return visitor.visitBoolEquals(this); - } - - public Expr getLeft() { - return expectTwoArgs().left; - } - - public Expr getRight() { - return expectTwoArgs().right; - } - - protected Type typecheckLocal(Scope scope) { - return ctx("while typechecking booleanEquals", this, () -> { - Pair args = expectTwoArgs(); - ctx("in the first argument", args.left, () -> args.left.typecheck(scope).expectBool()); - ctx("in the second argument", args.right, () -> args.right.typecheck(scope).expectBool()); - return Type.bool(); - }); - } - - @Override - public Value eval(Scope scope) { - Pair args = expectTwoArgs(); - return ctx("while evaluating boolEquals", this, () -> - Value.bool(args.left.eval(scope).expectBool() == args.right.eval(scope).expectBool())); - } -} diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/IsValidHostLabel.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/IsValidHostLabel.java deleted file mode 100644 index 79d96d282db..00000000000 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/IsValidHostLabel.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package software.amazon.smithy.rulesengine.language.lang.fn; - -import static software.amazon.smithy.rulesengine.language.error.RuleError.ctx; - -import software.amazon.smithy.rulesengine.language.eval.Scope; -import software.amazon.smithy.rulesengine.language.eval.Type; -import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.visit.FnVisitor; -import software.amazon.smithy.utils.SmithyUnstableApi; - -@SmithyUnstableApi -public final class IsValidHostLabel extends VarargFn { - public static final String ID = "isValidHostLabel"; - - public IsValidHostLabel(FnNode fnNode) { - super(fnNode); - } - - public static IsValidHostLabel ofExprs(Expr expr, boolean allowDots) { - return new IsValidHostLabel(FnNode.ofExprs(ID, expr, Expr.of(allowDots))); - } - - @Override - public T acceptFnVisitor(FnVisitor visitor) { - return visitor.visitIsValidHostLabel(this); - } - - public Expr hostLabel() { - return expectTwoArgs().left; - } - - public Expr allowDots() { - return expectTwoArgs().right; - } - - @Override - public Value eval(Scope scope) { - String hostLabel = expectTwoArgs().left.eval(scope).expectString(); - if (allowDots(scope)) { - return Value.bool(hostLabel.matches("[a-zA-Z\\d][a-zA-Z\\d\\-.]{0,62}")); - } else { - return Value.bool(hostLabel.matches("[a-zA-Z\\d][a-zA-Z\\d\\-]{0,62}")); - } - } - - protected Type typecheckLocal(Scope scope) { - return ctx( - "while typechecking isValidHostLabel", - this, - () -> { - allowDots().typecheck(scope).expectBool(); - hostLabel().typecheck(scope).expectString(); - return Type.bool(); - } - ); - } - - private boolean allowDots(Scope scope) { - return allowDots().eval(scope).expectBool(); - } -} diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/StringEquals.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/StringEquals.java deleted file mode 100644 index dda16178ec4..00000000000 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/StringEquals.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package software.amazon.smithy.rulesengine.language.lang.fn; - -import static software.amazon.smithy.rulesengine.language.error.RuleError.ctx; - -import software.amazon.smithy.rulesengine.language.eval.Scope; -import software.amazon.smithy.rulesengine.language.eval.Type; -import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.visit.FnVisitor; -import software.amazon.smithy.utils.Pair; -import software.amazon.smithy.utils.SmithyUnstableApi; - -@SmithyUnstableApi -public final class StringEquals extends Fn { - public static final String ID = "stringEquals"; - - public StringEquals(FnNode fnNode) { - super(fnNode); - } - - public static StringEquals ofExprs(Expr expr, Expr of) { - return new StringEquals(FnNode.ofExprs(ID, expr, of)); - } - - @Override - public T acceptFnVisitor(FnVisitor visitor) { - return visitor.visitStringEquals(this); - } - - public Expr getLeft() { - return expectTwoArgs().left; - } - - public Expr getRight() { - return expectTwoArgs().right; - } - - @Override - protected Type typecheckLocal(Scope scope) { - return ctx("while typechecking stringEquals", this, () -> { - Pair args = expectTwoArgs(); - ctx("in the first argument", args.left, () -> args.left.typecheck(scope).expectString()); - ctx("in the second argument", args.right, () -> args.right.typecheck(scope).expectString()); - return Type.bool(); - }); - } - - @Override - public Value eval(Scope scope) { - Pair args = expectTwoArgs(); - return Value.bool(args.left.eval(scope).expectString().equals(args.right.eval(scope).expectString())); - } -} diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/Substring.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/Substring.java deleted file mode 100644 index 10a10317037..00000000000 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/Substring.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package software.amazon.smithy.rulesengine.language.lang.fn; - -import static software.amazon.smithy.rulesengine.language.error.RuleError.ctx; - -import java.util.List; -import software.amazon.smithy.rulesengine.language.eval.Scope; -import software.amazon.smithy.rulesengine.language.eval.Type; -import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.Identifier; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.visit.FnVisitor; -import software.amazon.smithy.utils.SmithyUnstableApi; - -@SmithyUnstableApi -public final class Substring extends VarargFn { - public static final String ID = "substring"; - public static final Identifier SUBSTRING = Identifier.of("substring"); - private static final int EXPECTED_NUMBER_ARGS = 4; - - - public Substring(FnNode fnNode) { - super(fnNode); - } - - public static Substring ofExprs(Expr expr, int startIndex, int stopIndex, Boolean reverse) { - return new Substring(FnNode.ofExprs(ID, expr, Expr.of(startIndex), Expr.of(stopIndex), Expr.of(reverse))); - } - - @Override - public T acceptFnVisitor(FnVisitor visitor) { - return visitor.visitSubstring(this); - } - - public Expr stringToParse() { - return expectVariableArgs(EXPECTED_NUMBER_ARGS).get(0); - } - - public Expr startIndex() { - return expectVariableArgs(EXPECTED_NUMBER_ARGS).get(1); - } - - public Expr stopIndex() { - return expectVariableArgs(EXPECTED_NUMBER_ARGS).get(2); - } - - public Expr reverse() { - return expectVariableArgs(EXPECTED_NUMBER_ARGS).get(3); - } - - - @Override - public Value eval(Scope scope) { - List args = expectVariableArgs(EXPECTED_NUMBER_ARGS); - String str = args.get(0).eval(scope).expectString(); - int startIndex = args.get(1).eval(scope).expectInt(); - int stopIndex = args.get(2).eval(scope).expectInt(); - boolean reverse = args.get(3).eval(scope).expectBool(); - - if (!str.chars().allMatch(ch -> ch >= 0 && ch <= 127)) { - return Value.none(); - } - - if (startIndex >= stopIndex || str.length() < stopIndex) { - return new Value.None(); - } - - if (!reverse) { - return Value.str(str.substring(startIndex, stopIndex)); - } else { - int revStart = str.length() - stopIndex; - int revStop = str.length() - startIndex; - return Value.str(str.substring(revStart, revStop)); - } - } - - - @Override - protected Type typecheckLocal(Scope scope) { - return ctx( - "while typechecking substring", - this, - () -> { - stringToParse().typecheck(scope).expectString(); - startIndex().typecheck(scope).expectInt(); - stopIndex().typecheck(scope).expectInt(); - reverse().typecheck(scope).expectBool(); - return Type.optional(Type.str()); - } - ); - } - - -} diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/model/Outputs.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/model/Outputs.java index b1de65df48f..8d9b854c6af 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/model/Outputs.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/model/Outputs.java @@ -21,7 +21,7 @@ import software.amazon.smithy.model.SourceLocation; import software.amazon.smithy.model.node.Node; import software.amazon.smithy.model.node.ObjectNode; -import software.amazon.smithy.rulesengine.language.SourceAwareBuilder; +import software.amazon.smithy.rulesengine.language.util.SourceLocationTrackingBuilder; import software.amazon.smithy.utils.SmithyBuilder; import software.amazon.smithy.utils.SmithyUnstableApi; import software.amazon.smithy.utils.ToSmithyBuilder; @@ -118,7 +118,7 @@ public boolean equals(Object o) { && Objects.equals(dualStackDnsSuffix, outputs.dualStackDnsSuffix); } - public static class Builder extends SourceAwareBuilder { + public static class Builder extends SourceLocationTrackingBuilder { private String dnsSuffix; private String dualStackDnsSuffix; private boolean supportsFips; diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/model/Partition.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/model/Partition.java index cef6cabf311..55d50084978 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/model/Partition.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/model/Partition.java @@ -22,7 +22,7 @@ import software.amazon.smithy.model.SourceLocation; import software.amazon.smithy.model.node.Node; import software.amazon.smithy.model.node.ObjectNode; -import software.amazon.smithy.rulesengine.language.SourceAwareBuilder; +import software.amazon.smithy.rulesengine.language.util.SourceLocationTrackingBuilder; import software.amazon.smithy.utils.BuilderRef; import software.amazon.smithy.utils.SmithyBuilder; import software.amazon.smithy.utils.SmithyUnstableApi; @@ -120,10 +120,10 @@ public int hashCode() { return Objects.hash(id, regionRegex, regions, outputs); } - public static class Builder extends SourceAwareBuilder { + public static class Builder extends SourceLocationTrackingBuilder { private String id; private String regionRegex; - private BuilderRef> regions = BuilderRef.forOrderedMap(); + private final BuilderRef> regions = BuilderRef.forOrderedMap(); private Outputs outputs; public Builder(FromSourceLocation sourceLocation) { diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/model/Partitions.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/model/Partitions.java index abc1219d8ea..bef3d505084 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/model/Partitions.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/model/Partitions.java @@ -22,7 +22,7 @@ import software.amazon.smithy.model.SourceLocation; import software.amazon.smithy.model.node.Node; import software.amazon.smithy.model.node.ObjectNode; -import software.amazon.smithy.rulesengine.language.SourceAwareBuilder; +import software.amazon.smithy.rulesengine.language.util.SourceLocationTrackingBuilder; import software.amazon.smithy.utils.BuilderRef; import software.amazon.smithy.utils.SmithyBuilder; import software.amazon.smithy.utils.SmithyUnstableApi; @@ -107,7 +107,7 @@ public SmithyBuilder toBuilder() { .partitions(partitions); } - public static class Builder extends SourceAwareBuilder { + public static class Builder extends SourceLocationTrackingBuilder { private String version; private final BuilderRef> partitions = BuilderRef.forList(); diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/model/RegionOverride.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/model/RegionOverride.java index 160b69a8c8d..7aa67f2b120 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/model/RegionOverride.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/model/RegionOverride.java @@ -18,7 +18,7 @@ import software.amazon.smithy.model.FromSourceLocation; import software.amazon.smithy.model.SourceLocation; import software.amazon.smithy.model.node.Node; -import software.amazon.smithy.rulesengine.language.SourceAwareBuilder; +import software.amazon.smithy.rulesengine.language.util.SourceLocationTrackingBuilder; import software.amazon.smithy.utils.SmithyBuilder; import software.amazon.smithy.utils.SmithyUnstableApi; import software.amazon.smithy.utils.ToSmithyBuilder; @@ -60,7 +60,7 @@ public boolean equals(Object obj) { return obj instanceof RegionOverride; } - public static class Builder extends SourceAwareBuilder { + public static class Builder extends SourceLocationTrackingBuilder { public Builder(FromSourceLocation sourceLocation) { super(sourceLocation); diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/BooleanEquals.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/BooleanEquals.java new file mode 100644 index 00000000000..f47599f418d --- /dev/null +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/BooleanEquals.java @@ -0,0 +1,84 @@ +/* + * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.smithy.rulesengine.language.stdlib; + +import java.util.Arrays; +import java.util.List; +import software.amazon.smithy.rulesengine.language.error.InnerParseError; +import software.amazon.smithy.rulesengine.language.eval.Scope; +import software.amazon.smithy.rulesengine.language.eval.Type; +import software.amazon.smithy.rulesengine.language.eval.Value; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.fn.Fn; +import software.amazon.smithy.rulesengine.language.syntax.fn.FnNode; +import software.amazon.smithy.rulesengine.language.syntax.fn.FunctionDefinition; +import software.amazon.smithy.rulesengine.language.syntax.fn.LibraryFunction; +import software.amazon.smithy.rulesengine.language.syntax.parameters.Parameter; +import software.amazon.smithy.rulesengine.language.visit.ExprVisitor; +import software.amazon.smithy.utils.SmithyUnstableApi; + +@SmithyUnstableApi +public final class BooleanEquals extends Fn { + public static final String ID = "booleanEquals"; + private static final Defn DEFN = new Defn(); + + public BooleanEquals(FnNode fnNode) { + super(fnNode); + } + + public static Fn ofExprs(Expr left, Expr right) { + return LibraryFunction.ofExprs(DEFN, left, right); + } + + public static Fn fromParam(Parameter param, Expr value) { + return BooleanEquals.ofExprs(param.expr(), value); + } + + @Override + public R accept(ExprVisitor visitor) { + return visitor.visitBoolEquals(fnNode.getArgv().get(0), fnNode.getArgv().get(1)); + } + + @Override + protected Type typecheckLocal(Scope scope) throws InnerParseError { + LibraryFunction.checkTypeSignature(DEFN.arguments(), fnNode.getArgv(), scope); + return DEFN.returnType(); + } + + static class Defn extends FunctionDefinition { + public static final String ID = BooleanEquals.ID; + + @Override + public String id() { + return ID; + } + + @Override + public List arguments() { + return Arrays.asList(Type.bool(), Type.bool()); + } + + @Override + public Type returnType() { + return Type.bool(); + } + + @Override + public Value eval(List arguments) { + return Value.bool(arguments.get(0).expectBool() == arguments.get(1).expectBool()); + } + } +} diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/IsValidHostLabel.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/IsValidHostLabel.java new file mode 100644 index 00000000000..c191efd7997 --- /dev/null +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/IsValidHostLabel.java @@ -0,0 +1,61 @@ +/* + * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.smithy.rulesengine.language.stdlib; + +import java.util.Arrays; +import java.util.List; +import software.amazon.smithy.rulesengine.language.eval.Type; +import software.amazon.smithy.rulesengine.language.eval.Value; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.fn.Fn; +import software.amazon.smithy.rulesengine.language.syntax.fn.FunctionDefinition; +import software.amazon.smithy.rulesengine.language.syntax.fn.LibraryFunction; +import software.amazon.smithy.utils.SmithyUnstableApi; + +@SmithyUnstableApi +public final class IsValidHostLabel extends FunctionDefinition { + public static final String ID = "isValidHostLabel"; + + @Override + public String id() { + return ID; + } + + @Override + public List arguments() { + return Arrays.asList(Type.str(), Type.bool()); + } + + @Override + public Type returnType() { + return Type.bool(); + } + + @Override + public Value eval(List arguments) { + String hostLabel = arguments.get(0).expectString(); + boolean allowDots = arguments.get(1).expectBool(); + if (allowDots) { + return Value.bool(hostLabel.matches("[a-zA-Z\\d][a-zA-Z\\d\\-.]{0,62}")); + } else { + return Value.bool(hostLabel.matches("[a-zA-Z\\d][a-zA-Z\\d\\-]{0,62}")); + } + } + + public static Fn ofExprs(Expr input, boolean allowDots) { + return LibraryFunction.ofExprs(new IsValidHostLabel(), input, Expr.of(allowDots)); + } +} diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/ParseArn.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/ParseArn.java similarity index 71% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/ParseArn.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/ParseArn.java index 17a6d41b4a7..41c34e1908f 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/ParseArn.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/ParseArn.java @@ -13,22 +13,25 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.fn; +package software.amazon.smithy.rulesengine.language.stdlib; +import java.util.Collections; +import java.util.List; import java.util.Optional; import java.util.stream.Collectors; -import software.amazon.smithy.rulesengine.language.eval.Scope; import software.amazon.smithy.rulesengine.language.eval.Type; import software.amazon.smithy.rulesengine.language.eval.Value; import software.amazon.smithy.rulesengine.language.impl.Arn; -import software.amazon.smithy.rulesengine.language.lang.Identifier; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.visit.FnVisitor; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.fn.Fn; +import software.amazon.smithy.rulesengine.language.syntax.fn.FunctionDefinition; +import software.amazon.smithy.rulesengine.language.syntax.fn.LibraryFunction; import software.amazon.smithy.utils.MapUtils; import software.amazon.smithy.utils.SmithyUnstableApi; @SmithyUnstableApi -public final class ParseArn extends SingleArgFn { +public final class ParseArn extends FunctionDefinition { public static final String ID = "aws.parseArn"; public static final Identifier PARTITION = Identifier.of("partition"); public static final Identifier SERVICE = Identifier.of("service"); @@ -36,22 +39,31 @@ public final class ParseArn extends SingleArgFn { public static final Identifier ACCOUNT_ID = Identifier.of("accountId"); private static final Identifier RESOURCE_ID = Identifier.of("resourceId"); - public ParseArn(FnNode fnNode) { - super(fnNode, Type.str()); + + @Override + public String id() { + return ID; } - public static ParseArn ofExprs(Expr expr) { - return new ParseArn(FnNode.ofExprs(ID, expr)); + @Override + public List arguments() { + return Collections.singletonList(Type.str()); } @Override - public T acceptFnVisitor(FnVisitor visitor) { - return visitor.visitParseArn(this); + public Type returnType() { + return Type.optional(new Type.Record(MapUtils.of( + PARTITION, Type.str(), + SERVICE, Type.str(), + REGION, Type.str(), + ACCOUNT_ID, Type.str(), + RESOURCE_ID, Type.array(Type.str()) + ))); } @Override - protected Value evalArg(Value arg) { - String value = arg.expectString(); + public Value eval(List arguments) { + String value = arguments.get(0).expectString(); Optional arnOpt = Arn.parse(value); return arnOpt.map(arn -> (Value) Value.record(MapUtils.of( @@ -66,14 +78,7 @@ protected Value evalArg(Value arg) { ).orElse(new Value.None()); } - @Override - protected Type typecheckArg(Scope scope, Type.Str arg) { - return Type.optional(new Type.Record(MapUtils.of( - PARTITION, Type.str(), - SERVICE, Type.str(), - REGION, Type.str(), - ACCOUNT_ID, Type.str(), - RESOURCE_ID, Type.array(Type.str()) - ))); + public static Fn ofExprs(Expr expr) { + return LibraryFunction.ofExprs(new ParseArn(), expr); } } diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/ParseUrl.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/ParseUrl.java similarity index 80% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/ParseUrl.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/ParseUrl.java index 879b0d7db70..c5fd25cb82d 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/ParseUrl.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/ParseUrl.java @@ -13,17 +13,20 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.fn; +package software.amazon.smithy.rulesengine.language.stdlib; import java.net.MalformedURLException; import java.net.URL; import java.util.Arrays; -import software.amazon.smithy.rulesengine.language.eval.Scope; +import java.util.Collections; +import java.util.List; import software.amazon.smithy.rulesengine.language.eval.Type; import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.Identifier; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.visit.FnVisitor; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.fn.Fn; +import software.amazon.smithy.rulesengine.language.syntax.fn.FunctionDefinition; +import software.amazon.smithy.rulesengine.language.syntax.fn.LibraryFunction; import software.amazon.smithy.utils.MapUtils; import software.amazon.smithy.utils.SmithyUnstableApi; import software.amazon.smithy.utils.StringUtils; @@ -32,7 +35,7 @@ * Function to parse a URI from a string. */ @SmithyUnstableApi -public class ParseUrl extends SingleArgFn { +public class ParseUrl extends FunctionDefinition { public static final String ID = "parseURL"; public static final Identifier SCHEME = Identifier.of("scheme"); public static final Identifier AUTHORITY = Identifier.of("authority"); @@ -40,22 +43,37 @@ public class ParseUrl extends SingleArgFn { public static final Identifier NORMALIZED_PATH = Identifier.of("normalizedPath"); public static final Identifier IS_IP = Identifier.of("isIp"); - public ParseUrl(FnNode fnNode) { - super(fnNode, Type.str()); + + @Override + public String id() { + return "parseURL"; } - public static ParseUrl ofExprs(Expr expr) { - return new ParseUrl(FnNode.ofExprs(ID, expr)); + @Override + public List arguments() { + return Collections.singletonList(Type.str()); + } + + public static Fn ofExprs(Expr expr) { + return LibraryFunction.ofExprs(new ParseUrl(), expr); } @Override - public T acceptFnVisitor(FnVisitor visitor) { - return visitor.visitParseUrl(this); + public Type returnType() { + return Type.optional(Type.record( + MapUtils.of( + SCHEME, Type.str(), + AUTHORITY, Type.str(), + PATH, Type.str(), + NORMALIZED_PATH, Type.str(), + IS_IP, Type.bool() + ) + )); } @Override - protected Value evalArg(Value arg) { - String url = arg.expectString(); + public Value eval(List arguments) { + String url = arguments.get(0).expectString(); try { URL parsed = new URL(url); String path = parsed.getPath(); @@ -108,17 +126,4 @@ protected Value evalArg(Value arg) { return Value.none(); } } - - @Override - protected Type typecheckArg(Scope scope, Type.Str arg) { - return Type.optional(Type.record( - MapUtils.of( - SCHEME, Type.str(), - AUTHORITY, Type.str(), - PATH, Type.str(), - NORMALIZED_PATH, Type.str(), - IS_IP, Type.bool() - ) - )); - } } diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/PartitionFn.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/PartitionFn.java similarity index 79% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/PartitionFn.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/PartitionFn.java index ed71471a583..73a9c5e9e2c 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/PartitionFn.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/PartitionFn.java @@ -13,9 +13,10 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.fn; +package software.amazon.smithy.rulesengine.language.stdlib; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; @@ -23,23 +24,25 @@ import java.util.Map; import java.util.ServiceLoader; import java.util.regex.Pattern; -import software.amazon.smithy.rulesengine.language.eval.Scope; import software.amazon.smithy.rulesengine.language.eval.Type; import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.Identifier; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.lang.fn.partition.PartitionDataProvider; -import software.amazon.smithy.rulesengine.language.lang.parameters.Parameter; import software.amazon.smithy.rulesengine.language.model.Outputs; import software.amazon.smithy.rulesengine.language.model.Partition; import software.amazon.smithy.rulesengine.language.model.Partitions; +import software.amazon.smithy.rulesengine.language.stdlib.partition.PartitionDataProvider; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.fn.Fn; +import software.amazon.smithy.rulesengine.language.syntax.fn.FnNode; +import software.amazon.smithy.rulesengine.language.syntax.fn.FunctionDefinition; +import software.amazon.smithy.rulesengine.language.syntax.fn.LibraryFunction; +import software.amazon.smithy.rulesengine.language.syntax.parameters.Parameter; import software.amazon.smithy.rulesengine.language.util.LazyValue; -import software.amazon.smithy.rulesengine.language.visit.FnVisitor; import software.amazon.smithy.utils.MapUtils; import software.amazon.smithy.utils.SmithyUnstableApi; @SmithyUnstableApi -public final class PartitionFn extends SingleArgFn { +public final class PartitionFn extends FunctionDefinition { public static final String ID = "aws.partition"; public static final Identifier NAME = Identifier.of("name"); @@ -53,26 +56,30 @@ public final class PartitionFn extends SingleArgFn { .initializer(this::loadPartitionData) .build(); - public PartitionFn(FnNode node) { - super(node, Type.str()); - } - - public static PartitionFn ofExprs(Expr expr) { - return new PartitionFn(FnNode.ofExprs(ID, expr)); + @Override + public String id() { + return ID; } - public static PartitionFn fromParam(Parameter param) { - return PartitionFn.ofExprs(param.expr()); + @Override + public List arguments() { + return Collections.singletonList(Type.str()); } @Override - public T acceptFnVisitor(FnVisitor visitor) { - return visitor.visitPartition(this); + public Type returnType() { + LinkedHashMap type = new LinkedHashMap<>(); + type.put(NAME, Type.str()); + type.put(DNS_SUFFIX, Type.str()); + type.put(DUAL_STACK_DNS_SUFFIX, Type.str()); + type.put(SUPPORTS_DUAL_STACK, Type.bool()); + type.put(SUPPORTS_FIPS, Type.bool()); + return Type.optional(new Type.Record(type)); } @Override - public Value evalArg(Value arg) { - String regionName = arg.expectString(); + public Value eval(List arguments) { + String regionName = arguments.get(0).expectString(); final PartitionData data = partitionData.value(); @@ -107,23 +114,20 @@ public Value evalArg(Value arg) { INFERRED, Value.bool(inferred))); } - @Override - protected Type typecheckArg(Scope scope, Type.Str arg) { - LinkedHashMap type = new LinkedHashMap<>(); - type.put(NAME, Type.str()); - type.put(DNS_SUFFIX, Type.str()); - type.put(DUAL_STACK_DNS_SUFFIX, Type.str()); - type.put(SUPPORTS_DUAL_STACK, Type.bool()); - type.put(SUPPORTS_FIPS, Type.bool()); - return Type.optional(new Type.Record(type)); + public static Fn ofExprs(Expr expr) { + return new LibraryFunction(new PartitionFn(), FnNode.ofExprs(ID, expr)); + } + + public static Fn fromParam(Parameter param) { + return PartitionFn.ofExprs(param.expr()); } + private PartitionData loadPartitionData() { Iterator iter = ServiceLoader.load(PartitionDataProvider.class).iterator(); if (!iter.hasNext()) { throw new RuntimeException("Unable to locate partition data"); } - ; PartitionDataProvider provider = iter.next(); diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/StringEquals.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/StringEquals.java new file mode 100644 index 00000000000..a865c3aa3a0 --- /dev/null +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/StringEquals.java @@ -0,0 +1,80 @@ +/* + * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.smithy.rulesengine.language.stdlib; + +import java.util.Arrays; +import java.util.List; +import software.amazon.smithy.rulesengine.language.error.InnerParseError; +import software.amazon.smithy.rulesengine.language.eval.Scope; +import software.amazon.smithy.rulesengine.language.eval.Type; +import software.amazon.smithy.rulesengine.language.eval.Value; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.fn.Fn; +import software.amazon.smithy.rulesengine.language.syntax.fn.FnNode; +import software.amazon.smithy.rulesengine.language.syntax.fn.FunctionDefinition; +import software.amazon.smithy.rulesengine.language.syntax.fn.LibraryFunction; +import software.amazon.smithy.rulesengine.language.visit.ExprVisitor; +import software.amazon.smithy.utils.SmithyUnstableApi; + +@SmithyUnstableApi +public final class StringEquals extends Fn { + public static final String ID = "stringEquals"; + private static final Defn DEFN = new Defn(); + + public StringEquals(FnNode fnNode) { + super(fnNode); + } + + public static Fn ofExprs(Expr left, Expr right) { + return LibraryFunction.ofExprs(DEFN, left, right); + } + + @Override + public R accept(ExprVisitor visitor) { + return visitor.visitStringEquals(fnNode.getArgv().get(0), fnNode.getArgv().get(1)); + } + + @Override + protected Type typecheckLocal(Scope scope) throws InnerParseError { + LibraryFunction.checkTypeSignature(DEFN.arguments(), fnNode.getArgv(), scope); + return DEFN.returnType(); + } + + private static class Defn extends FunctionDefinition { + public static final String ID = StringEquals.ID; + + + @Override + public String id() { + return ID; + } + + @Override + public List arguments() { + return Arrays.asList(Type.str(), Type.str()); + } + + @Override + public Type returnType() { + return Type.bool(); + } + + @Override + public Value eval(List arguments) { + return Value.bool(arguments.get(0).expectString().equals(arguments.get(1).expectString())); + } + } +} diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/Substring.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/Substring.java new file mode 100644 index 00000000000..1f52446a55f --- /dev/null +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/Substring.java @@ -0,0 +1,77 @@ +/* + * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.smithy.rulesengine.language.stdlib; + +import java.util.Arrays; +import java.util.List; +import software.amazon.smithy.rulesengine.language.eval.Type; +import software.amazon.smithy.rulesengine.language.eval.Value; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.fn.Fn; +import software.amazon.smithy.rulesengine.language.syntax.fn.FunctionDefinition; +import software.amazon.smithy.rulesengine.language.syntax.fn.LibraryFunction; +import software.amazon.smithy.utils.SmithyUnstableApi; + +@SmithyUnstableApi +public final class Substring extends FunctionDefinition { + public static final String ID = "substring"; + + @Override + public String id() { + return ID; + } + + @Override + public List arguments() { + return Arrays.asList(Type.str(), Type.integer(), Type.integer(), Type.bool()); + } + + @Override + public Type returnType() { + return Type.str(); + } + + @Override + public Value eval(List arguments) { + String str = arguments.get(0).expectString(); + int startIndex = arguments.get(1).expectInt(); + int stopIndex = arguments.get(2).expectInt(); + boolean reverse = arguments.get(3).expectBool(); + + if (!str.chars().allMatch(ch -> ch >= 0 && ch <= 127)) { + return Value.none(); + } + + if (startIndex >= stopIndex || str.length() < stopIndex) { + return new Value.None(); + } + + if (!reverse) { + return Value.str(str.substring(startIndex, stopIndex)); + } else { + int revStart = str.length() - stopIndex; + int revStop = str.length() - startIndex; + return Value.str(str.substring(revStart, revStop)); + } + } + + public static Fn ofExprs(Expr str, int startIndex, int stopIndex, Boolean reverse) { + return LibraryFunction.ofExprs( + new Substring(), + str, Expr.of(startIndex), Expr.of(stopIndex), Expr.of(reverse) + ); + } +} diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/UriEncode.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/UriEncode.java similarity index 62% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/UriEncode.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/UriEncode.java index 9368bd9be59..bcbdbebf6b7 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/UriEncode.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/UriEncode.java @@ -13,45 +13,47 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.fn; +package software.amazon.smithy.rulesengine.language.stdlib; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; -import software.amazon.smithy.rulesengine.language.eval.Scope; +import java.util.Collections; +import java.util.List; import software.amazon.smithy.rulesengine.language.eval.Type; import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.lang.parameters.Parameter; -import software.amazon.smithy.rulesengine.language.visit.FnVisitor; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.fn.Fn; +import software.amazon.smithy.rulesengine.language.syntax.fn.FunctionDefinition; +import software.amazon.smithy.rulesengine.language.syntax.fn.LibraryFunction; +import software.amazon.smithy.rulesengine.language.syntax.parameters.Parameter; import software.amazon.smithy.utils.SmithyUnstableApi; @SmithyUnstableApi -public final class UriEncode extends SingleArgFn { +public final class UriEncode extends FunctionDefinition { public static final String ID = "uriEncode"; private static final String[] ENCODED_CHARACTERS = new String[]{"+", "*", "%7E"}; private static final String[] ENCODED_CHARACTERS_REPLACEMENTS = new String[]{"%20", "%2A", "~"}; - public UriEncode(FnNode node) { - super(node, Type.str()); - } - public static UriEncode ofExprs(Expr expr) { - return new UriEncode(FnNode.ofExprs(ID, expr)); + @Override + public String id() { + return ID; } - public static UriEncode fromParam(Parameter param) { - return UriEncode.ofExprs(param.expr()); + @Override + public List arguments() { + return Collections.singletonList(Type.str()); } @Override - public T acceptFnVisitor(FnVisitor visitor) { - return visitor.visitUriEncode(this); + public Type returnType() { + return Type.str(); } @Override - protected Value evalArg(Value arg) { - String url = arg.expectString(); + public Value eval(List arguments) { + String url = arguments.get(0).expectString(); try { String encoded = URLEncoder.encode(url, "UTF-8"); for (int i = 0; i < ENCODED_CHARACTERS.length; i++) { @@ -63,8 +65,11 @@ protected Value evalArg(Value arg) { } } - @Override - protected Type typecheckArg(Scope scope, Type.Str arg) { - return Type.str(); + public static Fn ofExprs(Expr expr) { + return LibraryFunction.ofExprs(new UriEncode(), expr); + } + + public static Fn fromParam(Parameter param) { + return UriEncode.ofExprs(param.expr()); } } diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/partition/DefaultPartitionDataProvider.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/partition/DefaultPartitionDataProvider.java similarity index 94% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/partition/DefaultPartitionDataProvider.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/partition/DefaultPartitionDataProvider.java index d34eef2457f..3f4d468ac28 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/partition/DefaultPartitionDataProvider.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/partition/DefaultPartitionDataProvider.java @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.fn.partition; +package software.amazon.smithy.rulesengine.language.stdlib.partition; import java.io.InputStream; import software.amazon.smithy.model.node.Node; diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/partition/PartitionDataProvider.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/partition/PartitionDataProvider.java similarity index 91% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/partition/PartitionDataProvider.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/partition/PartitionDataProvider.java index 11f03fd8e5e..bcee9bdd0e4 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/partition/PartitionDataProvider.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/stdlib/partition/PartitionDataProvider.java @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.fn.partition; +package software.amazon.smithy.rulesengine.language.stdlib.partition; import software.amazon.smithy.rulesengine.language.model.Partitions; import software.amazon.smithy.utils.SmithyUnstableApi; diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/Identifier.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/Identifier.java similarity index 77% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/Identifier.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/Identifier.java index a8a789b229f..0864731d83c 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/Identifier.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/Identifier.java @@ -13,27 +13,27 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang; +package software.amazon.smithy.rulesengine.language.syntax; import java.util.Objects; -import software.amazon.smithy.model.FromSourceLocation; -import software.amazon.smithy.model.SourceLocation; import software.amazon.smithy.model.node.Node; import software.amazon.smithy.model.node.StringNode; import software.amazon.smithy.model.node.ToNode; -import software.amazon.smithy.rulesengine.language.SourceAwareBuilder; +import software.amazon.smithy.rulesengine.language.util.MandatorySourceLocation; +import software.amazon.smithy.rulesengine.language.util.SourceLocationHelpers; import software.amazon.smithy.utils.SmithyUnstableApi; @SmithyUnstableApi -public final class Identifier implements FromSourceLocation, ToNode { +public final class Identifier extends MandatorySourceLocation implements ToNode { private final StringNode name; Identifier(StringNode name) { + super(name); this.name = name; } public static Identifier of(String name) { - return new Identifier(new StringNode(name, SourceAwareBuilder.javaLocation())); + return new Identifier(new StringNode(name, SourceLocationHelpers.javaLocation())); } public static Identifier of(StringNode name) { @@ -65,11 +65,6 @@ public String toString() { return name.getValue(); } - @Override - public SourceLocation getSourceLocation() { - return name.getSourceLocation(); - } - public String asString() { return name.getValue(); } diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/expr/Expr.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expr/Expr.java similarity index 76% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/expr/Expr.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expr/Expr.java index 6c8a2c926f8..299691b3463 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/expr/Expr.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expr/Expr.java @@ -13,46 +13,48 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.expr; +package software.amazon.smithy.rulesengine.language.syntax.expr; import static software.amazon.smithy.rulesengine.language.error.RuleError.ctx; -import java.util.Objects; import java.util.Optional; import software.amazon.smithy.model.FromSourceLocation; import software.amazon.smithy.model.SourceException; -import software.amazon.smithy.model.SourceLocation; import software.amazon.smithy.model.node.Node; import software.amazon.smithy.model.node.ObjectNode; import software.amazon.smithy.model.node.StringNode; import software.amazon.smithy.model.node.ToNode; import software.amazon.smithy.rulesengine.language.error.InnerParseError; -import software.amazon.smithy.rulesengine.language.eval.Eval; import software.amazon.smithy.rulesengine.language.eval.Scope; import software.amazon.smithy.rulesengine.language.eval.Type; import software.amazon.smithy.rulesengine.language.eval.Typecheck; -import software.amazon.smithy.rulesengine.language.lang.Identifier; -import software.amazon.smithy.rulesengine.language.lang.fn.BooleanEquals; -import software.amazon.smithy.rulesengine.language.lang.fn.FnNode; -import software.amazon.smithy.rulesengine.language.lang.fn.GetAttr; -import software.amazon.smithy.rulesengine.language.lang.fn.IsSet; -import software.amazon.smithy.rulesengine.language.lang.fn.IsValidHostLabel; -import software.amazon.smithy.rulesengine.language.lang.fn.Not; -import software.amazon.smithy.rulesengine.language.lang.fn.ParseArn; -import software.amazon.smithy.rulesengine.language.lang.fn.ParseUrl; -import software.amazon.smithy.rulesengine.language.lang.fn.StringEquals; -import software.amazon.smithy.rulesengine.language.lang.fn.Substring; +import software.amazon.smithy.rulesengine.language.stdlib.BooleanEquals; +import software.amazon.smithy.rulesengine.language.stdlib.IsValidHostLabel; +import software.amazon.smithy.rulesengine.language.stdlib.ParseArn; +import software.amazon.smithy.rulesengine.language.stdlib.ParseUrl; +import software.amazon.smithy.rulesengine.language.stdlib.StringEquals; +import software.amazon.smithy.rulesengine.language.stdlib.Substring; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.fn.Fn; +import software.amazon.smithy.rulesengine.language.syntax.fn.FnNode; +import software.amazon.smithy.rulesengine.language.syntax.fn.GetAttr; +import software.amazon.smithy.rulesengine.language.syntax.fn.IsSet; +import software.amazon.smithy.rulesengine.language.syntax.fn.Not; +import software.amazon.smithy.rulesengine.language.util.MandatorySourceLocation; import software.amazon.smithy.rulesengine.language.visit.ExprVisitor; import software.amazon.smithy.utils.SmithyUnstableApi; +/** + * A dynamically computed expression. + *

+ * Expressions are the fundamental building block of the rule language. + */ @SmithyUnstableApi -public abstract class Expr implements FromSourceLocation, Typecheck, Eval, ToNode { - private final SourceLocation sourceLocation; - +public abstract class Expr extends MandatorySourceLocation implements Typecheck, ToNode { private Type cachedType; - public Expr(SourceLocation sourceLocation) { - this.sourceLocation = Objects.requireNonNull(sourceLocation); + public Expr(FromSourceLocation sourceLocation) { + super(sourceLocation); } public static Expr of(boolean value) { @@ -114,10 +116,6 @@ public static Literal literal(StringNode node) { return Literal.str(new Template(node)); } - public SourceLocation getSourceLocation() { - return this.sourceLocation; - } - public abstract R accept(ExprVisitor visitor); @Override @@ -160,7 +158,7 @@ public IsSet isSet() { return IsSet.ofExpr(this); } - public BooleanEquals eq(boolean value) { + public Fn eq(boolean value) { return BooleanEquals.ofExprs(this, Expr.of(value)); } @@ -168,23 +166,23 @@ public Not not() { return Not.ofExpr(this); } - public StringEquals eq(String value) { + public Fn eq(String value) { return StringEquals.ofExprs(this, Expr.of(value)); } - public ParseArn parseArn() { + public Fn parseArn() { return ParseArn.ofExprs(this); } - public Substring substring(int startIndex, int stopIndex, Boolean reverse) { + public Fn substring(int startIndex, int stopIndex, Boolean reverse) { return Substring.ofExprs(this, startIndex, stopIndex, reverse); } - public IsValidHostLabel isValidHostLabel(boolean allowDots) { + public Fn isValidHostLabel(boolean allowDots) { return IsValidHostLabel.ofExprs(this, allowDots); } - public ParseUrl parseUrl() { + public Fn parseUrl() { return ParseUrl.ofExprs(this); } diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/expr/Literal.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expr/Literal.java similarity index 85% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/expr/Literal.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expr/Literal.java index ece3402e18d..fe36a16da8d 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/expr/Literal.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expr/Literal.java @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.expr; +package software.amazon.smithy.rulesengine.language.syntax.expr; import java.util.ArrayList; import java.util.HashMap; @@ -33,15 +33,23 @@ import software.amazon.smithy.model.node.NumberNode; import software.amazon.smithy.model.node.ObjectNode; import software.amazon.smithy.model.node.StringNode; -import software.amazon.smithy.rulesengine.language.SourceAwareBuilder; import software.amazon.smithy.rulesengine.language.error.RuleError; +import software.amazon.smithy.rulesengine.language.eval.RuleEvaluator; import software.amazon.smithy.rulesengine.language.eval.Scope; import software.amazon.smithy.rulesengine.language.eval.Type; import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.util.SourceLocationHelpers; import software.amazon.smithy.rulesengine.language.visit.ExprVisitor; +import software.amazon.smithy.rulesengine.language.visit.TemplateVisitor; import software.amazon.smithy.utils.SmithyUnstableApi; +/** + * Literals allow rules and properties to define arbitrarily nested JSON structures (e.g.for properties) + *

+ * They support template strings, but _do not_ support template objects since that creates ambiguity. {@link Template}s + * are a basic example of literals–literal strings. Literals can also be booleans, objects, integers or tuples. + */ @SmithyUnstableApi public final class Literal extends Expr { @@ -53,23 +61,23 @@ private Literal(Lit source, FromSourceLocation sourceLocation) { } public static Literal tuple(List authSchemes) { - return new Literal(new Tuple(authSchemes), SourceAwareBuilder.javaLocation()); + return new Literal(new Tuple(authSchemes), SourceLocationHelpers.javaLocation()); } public static Literal record(Map record) { - return new Literal(new Obj(record), SourceAwareBuilder.javaLocation()); + return new Literal(new Obj(record), SourceLocationHelpers.javaLocation()); } public static Literal str(Template value) { - return new Literal(new Str(value), SourceAwareBuilder.javaLocation()); + return new Literal(new Str(value), SourceLocationHelpers.javaLocation()); } public static Literal integer(int value) { - return new Literal(new Int(Node.from(value)), SourceAwareBuilder.javaLocation()); + return new Literal(new Int(Node.from(value)), SourceLocationHelpers.javaLocation()); } public static Literal bool(boolean value) { - return new Literal(new Bool(Node.from(value)), SourceAwareBuilder.javaLocation()); + return new Literal(new Bool(Node.from(value)), SourceLocationHelpers.javaLocation()); } public static Literal fromNode(Node node) { @@ -220,8 +228,7 @@ public Type typecheckLocal(Scope scope) { return nodeToType(source, scope); } - @Override - public Value eval(Scope scope) { + public Value eval(RuleEvaluator evaluator) { return source.accept(new Vistor() { @Override public Value visitBool(boolean b) { @@ -230,14 +237,44 @@ public Value visitBool(boolean b) { @Override public Value visitStr(Template value) { - return value.eval(scope); + return Value.str(value.accept(new TemplateVisitor() { + @Override + public String visitStaticTemplate(String value) { + return value; + } + + @Override + public String visitSingleDynamicTemplate(Expr value) { + return value.accept(evaluator).expectString(); + } + + @Override + public String visitStaticElement(String value) { + return value; + } + + @Override + public String visitDynamicElement(Expr value) { + return value.accept(evaluator).expectString(); + } + + @Override + public String startMultipartTemplate() { + return ""; + } + + @Override + public String finishMultipartTemplate() { + return ""; + } + }).collect(Collectors.joining())); } @Override public Value visitObject(Map members) { Map tpe = new HashMap<>(); members.forEach((k, v) -> { - tpe.put(k, v.eval(scope)); + tpe.put(k, v.accept(evaluator)); }); return Value.record(tpe); } @@ -246,7 +283,7 @@ public Value visitObject(Map members) { public Value visitTuple(List members) { List tuples = new ArrayList<>(); for (Literal el : ((Tuple) source).members) { - tuples.add(el.eval(scope)); + tuples.add(el.accept(evaluator)); } return Value.array(tuples); } diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/expr/Ref.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expr/Ref.java similarity index 89% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/expr/Ref.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expr/Ref.java index 0d09d38ad31..b0b4f76ef6e 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/expr/Ref.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expr/Ref.java @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.expr; +package software.amazon.smithy.rulesengine.language.syntax.expr; import static software.amazon.smithy.rulesengine.language.error.RuleError.ctx; @@ -23,8 +23,7 @@ import software.amazon.smithy.model.node.ObjectNode; import software.amazon.smithy.rulesengine.language.eval.Scope; import software.amazon.smithy.rulesengine.language.eval.Type; -import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; import software.amazon.smithy.rulesengine.language.visit.ExprVisitor; import software.amazon.smithy.utils.SmithyUnstableApi; @@ -92,11 +91,6 @@ public String toString() { return name.asString(); } - @Override - public Value eval(Scope scope) { - return scope.getValue(this.name).orElse(new Value.None()); - } - @Override public Node toNode() { return ObjectNode.builder() diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/expr/Template.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expr/Template.java similarity index 89% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/expr/Template.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expr/Template.java index c9735e0693f..34affc3b4ae 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/expr/Template.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/expr/Template.java @@ -13,10 +13,10 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.expr; +package software.amazon.smithy.rulesengine.language.syntax.expr; import static software.amazon.smithy.rulesengine.language.error.RuleError.ctx; -import static software.amazon.smithy.rulesengine.language.lang.expr.Expr.parseShortform; +import static software.amazon.smithy.rulesengine.language.syntax.expr.Expr.parseShortform; import java.util.ArrayList; import java.util.List; @@ -25,7 +25,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import software.amazon.smithy.model.FromSourceLocation; -import software.amazon.smithy.model.SourceLocation; import software.amazon.smithy.model.node.Node; import software.amazon.smithy.model.node.StringNode; import software.amazon.smithy.model.node.ToNode; @@ -33,7 +32,7 @@ import software.amazon.smithy.rulesengine.language.eval.Scope; import software.amazon.smithy.rulesengine.language.eval.Type; import software.amazon.smithy.rulesengine.language.eval.Typecheck; -import software.amazon.smithy.rulesengine.language.eval.Value; +import software.amazon.smithy.rulesengine.language.util.MandatorySourceLocation; import software.amazon.smithy.rulesengine.language.visit.TemplateVisitor; import software.amazon.smithy.utils.SmithyUnstableApi; @@ -47,15 +46,14 @@ * Dynamic getAttr short form */ @SmithyUnstableApi -public final class Template implements FromSourceLocation, ToNode { +public final class Template extends MandatorySourceLocation implements ToNode { private final List parts; - private final SourceLocation sourceLocation; Template(StringNode template) { + super(template); this.parts = ctx("when parsing template", template, () -> parseTemplate(template.getValue(), template)); - sourceLocation = template.getSourceLocation(); } public static Template fromString(String s) { @@ -89,10 +87,6 @@ public String expectLiteral() { return this.parts.stream().map(Part::toString).collect(Collectors.joining()); } - @Override - public SourceLocation getSourceLocation() { - return sourceLocation; - } @Override public int hashCode() { @@ -141,10 +135,6 @@ public Node toNode() { return Node.from(sb.toString()); } - public Value eval(Scope scope) { - return Value.str(parts.stream().map(part -> part.eval(scope)).collect(Collectors.joining())); - } - private List parseTemplate(String template, FromSourceLocation context) throws InnerParseError { ArrayList out = new ArrayList<>(); @@ -191,7 +181,6 @@ private List parseTemplate(String template, FromSourceLocation context) } public abstract static class Part implements Typecheck { - abstract String eval(Scope scope); abstract T accept(TemplateVisitor visitor); @@ -217,11 +206,6 @@ public String getValue() { return value; } - @Override - String eval(Scope scope) { - return this.value; - } - @Override T accept(TemplateVisitor visitor) { return visitor.visitStaticElement(this.value); @@ -268,11 +252,6 @@ public static Dynamic parse(String value, FromSourceLocation context) { return new Dynamic(value, parseShortform(value, context)); } - @Override - String eval(Scope scope) { - return ctx("while evaluating " + this, () -> expr.eval(scope).expectString()); - } - @Override T accept(TemplateVisitor visitor) { return visitor.visitDynamicElement(this.expr); @@ -301,7 +280,7 @@ public int hashCode() { @Override public String toString() { - return String.format("{dyn %s}", this.raw); + return String.format("{%s}", this.raw); } @Override diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/Fn.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/Fn.java similarity index 68% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/Fn.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/Fn.java index a83ea759203..c34c5090e1d 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/Fn.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/Fn.java @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.fn; +package software.amazon.smithy.rulesengine.language.syntax.fn; import java.util.List; import java.util.Objects; @@ -23,16 +23,13 @@ import software.amazon.smithy.model.node.Node; import software.amazon.smithy.rulesengine.Into; import software.amazon.smithy.rulesengine.language.error.RuleError; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.lang.rule.Condition; -import software.amazon.smithy.rulesengine.language.visit.ExprVisitor; -import software.amazon.smithy.rulesengine.language.visit.FnVisitor; -import software.amazon.smithy.utils.Pair; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.rule.Condition; import software.amazon.smithy.utils.SmithyUnstableApi; @SmithyUnstableApi public abstract class Fn extends Expr implements Into { - protected FnNode fnNode; + protected final FnNode fnNode; public Fn(FnNode fnNode) { super(fnNode.getSourceLocation()); @@ -50,8 +47,6 @@ public Condition condition(String result) { return new Condition.Builder().fn(this).result(result).build(); } - public abstract T acceptFnVisitor(FnVisitor visitor); - /** * Returns the name of this function, eg. {@code isSet}, {@code parseUrl} * @@ -91,10 +86,6 @@ public SourceLocation getSourceLocation() { return fnNode.getSourceLocation(); } - public R accept(ExprVisitor visitor) { - return visitor.visitFn(this); - } - @Override public boolean equals(Object obj) { if (obj == this) { @@ -116,30 +107,6 @@ public Node toNode() { return fnNode.toNode(); } - protected Pair expectTwoArgs() { - List argv = this.fnNode.getArgv(); - if (argv.size() == 2) { - return Pair.of(argv.get(0), argv.get(1)); - } else { - throw new RuleError( - new SourceException("expected 2 arguments but found " + argv.size(), - this.fnNode)); - } - - } - - protected List expectVariableArgs(int expectedNumberArgs) { - List argv = this.fnNode.getArgv(); - if (argv.size() == expectedNumberArgs) { - return argv; - } else { - throw new RuleError( - new SourceException(String.format("expected %d arguments but found %d", - expectedNumberArgs, argv.size()), this.fnNode)); - } - - } - @Override public Condition into() { return this.condition(); diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/FnNode.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/FnNode.java similarity index 81% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/FnNode.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/FnNode.java index 2815a8ca25c..6f2a6efa228 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/FnNode.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/FnNode.java @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.fn; +package software.amazon.smithy.rulesengine.language.syntax.fn; import java.util.Arrays; import java.util.List; @@ -27,9 +27,11 @@ import software.amazon.smithy.model.node.ObjectNode; import software.amazon.smithy.model.node.StringNode; import software.amazon.smithy.model.node.ToNode; -import software.amazon.smithy.rulesengine.language.SourceAwareBuilder; import software.amazon.smithy.rulesengine.language.error.RuleError; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; +import software.amazon.smithy.rulesengine.language.stdlib.BooleanEquals; +import software.amazon.smithy.rulesengine.language.stdlib.StringEquals; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.util.SourceLocationTrackingBuilder; import software.amazon.smithy.utils.BuilderRef; import software.amazon.smithy.utils.SmithyBuilder; import software.amazon.smithy.utils.SmithyUnstableApi; @@ -77,34 +79,26 @@ public static Builder builder(FromSourceLocation sourceLocation) { return new Builder(sourceLocation); } - public Fn validate() { + public Expr validate() { switch (fn.getValue()) { - case BooleanEquals.ID: - return new BooleanEquals(this); - case PartitionFn.ID: - return new PartitionFn(this); - case StringEquals.ID: - return new StringEquals(this); case IsSet.ID: return new IsSet(this); - case IsValidHostLabel.ID: - return new IsValidHostLabel(this); case GetAttr.ID: - return new GetAttr(this); - case ParseArn.ID: - return new ParseArn(this); + return GetAttr.builder(this) + .target(getArgv().get(0)) + .path(getArgv().get(1).toNode().expectStringNode().getValue()) + .build(); case Not.ID: return new Not(this); - case ParseUrl.ID: - return new ParseUrl(this); - case Substring.ID: - return new Substring(this); - case UriEncode.ID: - return new UriEncode(this); + case BooleanEquals.ID: + return new BooleanEquals(this); + case StringEquals.ID: + return new StringEquals(this); default: - throw new RuleError( - new SourceException( - String.format("`%s` is not a valid function", fn), fn)); + return FunctionRegistry.getGlobalRegistry().forNode(this).orElseThrow(() -> + new RuleError( + new SourceException( + String.format("`%s` is not a valid function", fn), fn))); } } @@ -149,9 +143,9 @@ public boolean equals(Object o) { return fn.equals(fnNode.fn) && argv.equals(fnNode.argv); } - public static class Builder extends SourceAwareBuilder { + public static class Builder extends SourceLocationTrackingBuilder { private StringNode fn; - private BuilderRef> argv = BuilderRef.forList(); + private final BuilderRef> argv = BuilderRef.forList(); public Builder(FromSourceLocation sourceLocation) { super(sourceLocation); diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/VarargFn.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/FunctionDefinition.java similarity index 53% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/VarargFn.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/FunctionDefinition.java index 1c8715525e2..5b42df4bf01 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/VarargFn.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/FunctionDefinition.java @@ -13,26 +13,40 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.fn; +package software.amazon.smithy.rulesengine.language.syntax.fn; import java.util.List; -import software.amazon.smithy.rulesengine.language.eval.Scope; import software.amazon.smithy.rulesengine.language.eval.Type; import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; import software.amazon.smithy.utils.SmithyUnstableApi; @SmithyUnstableApi -abstract class VarargFn extends Fn { - VarargFn(FnNode fnNode) { - super(fnNode); +public abstract class FunctionDefinition { + public FunctionDefinition() { } - public abstract Value eval(Scope scope); + /** + * The ID of this function. + * @return The ID string + */ + public abstract String id(); - protected abstract Type typecheckLocal(Scope scope); + /** + * The arguments to this function. + * @return The function arguments + */ + public abstract List arguments(); + + /** + * The return type of this function definition. + * @return The function return type + */ + public abstract Type returnType(); + + /** + * Evaluate the arguments to a given function to compute a result. + * @return The resulting value + */ + public abstract Value eval(List arguments); - protected List args() { - return this.fnNode.getArgv(); - } } diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/FunctionRegistry.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/FunctionRegistry.java new file mode 100644 index 00000000000..f16db642251 --- /dev/null +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/FunctionRegistry.java @@ -0,0 +1,66 @@ +/* + * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.smithy.rulesengine.language.syntax.fn; + +import java.util.HashMap; +import java.util.Optional; +import software.amazon.smithy.rulesengine.language.stdlib.IsValidHostLabel; +import software.amazon.smithy.rulesengine.language.stdlib.ParseArn; +import software.amazon.smithy.rulesengine.language.stdlib.ParseUrl; +import software.amazon.smithy.rulesengine.language.stdlib.PartitionFn; +import software.amazon.smithy.rulesengine.language.stdlib.Substring; +import software.amazon.smithy.rulesengine.language.stdlib.UriEncode; +import software.amazon.smithy.rulesengine.language.util.LazyValue; +import software.amazon.smithy.utils.SmithyUnstableApi; + +/** + * Collection of registered functions. + */ +@SmithyUnstableApi +public final class FunctionRegistry { + private static final LazyValue GLOBAL_REGISTRY = + LazyValue.builder().initializer(() -> { + FunctionRegistry registry = new FunctionRegistry(); + registry.registerFunction(new PartitionFn()); + registry.registerFunction(new IsValidHostLabel()); + registry.registerFunction(new ParseArn()); + registry.registerFunction(new ParseUrl()); + registry.registerFunction(new Substring()); + registry.registerFunction(new UriEncode()); + return registry; + }).build(); + + private final HashMap registry = new HashMap<>(); + + private FunctionRegistry() { + } + + public void registerFunction(FunctionDefinition definition) { + registry.put(definition.id(), definition); + } + + public Optional forNode(FnNode node) { + if (registry.containsKey(node.getId())) { + return Optional.of(new LibraryFunction(registry.get(node.getId()), node)); + } else { + return Optional.empty(); + } + } + + static FunctionRegistry getGlobalRegistry() { + return GLOBAL_REGISTRY.value(); + } +} diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/GetAttr.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/GetAttr.java similarity index 64% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/GetAttr.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/GetAttr.java index 1569c88e70e..fcbcc4b77c8 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/GetAttr.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/GetAttr.java @@ -13,53 +13,54 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.fn; +package software.amazon.smithy.rulesengine.language.syntax.fn; import static software.amazon.smithy.rulesengine.language.error.RuleError.ctx; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Objects; import software.amazon.smithy.model.FromSourceLocation; -import software.amazon.smithy.model.SourceException; +import software.amazon.smithy.model.node.ArrayNode; +import software.amazon.smithy.model.node.Node; +import software.amazon.smithy.model.node.ObjectNode; import software.amazon.smithy.model.node.StringNode; -import software.amazon.smithy.rulesengine.language.SourceAwareBuilder; import software.amazon.smithy.rulesengine.language.error.InnerParseError; +import software.amazon.smithy.rulesengine.language.error.InvalidRulesException; import software.amazon.smithy.rulesengine.language.eval.Scope; import software.amazon.smithy.rulesengine.language.eval.Type; import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.Identifier; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.lang.expr.Literal; -import software.amazon.smithy.rulesengine.language.lang.expr.Ref; -import software.amazon.smithy.rulesengine.language.visit.FnVisitor; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.expr.Ref; +import software.amazon.smithy.rulesengine.language.util.SourceLocationTrackingBuilder; +import software.amazon.smithy.rulesengine.language.visit.ExprVisitor; import software.amazon.smithy.utils.SmithyUnstableApi; @SmithyUnstableApi -public final class GetAttr extends Fn { +public final class GetAttr extends Expr { public static final String ID = "getAttr"; + private final Expr target; + private final List path; - public GetAttr(FnNode node) { - super(node); - } - - private static GetAttr fromBuilder(Builder builder) { - return new GetAttr(FnNode - .builder(builder.getSourceLocation()) - .fn(StringNode.from("getAttr")) - .argv( - Arrays.asList( - builder.target, - Literal.of(String.join(".", builder.path)))) - .build()); + private GetAttr(Builder builder) { + super(builder.getSourceLocation()); + this.target = builder.target; + this.path = parse(builder.path, builder.getSourceLocation()); } public static Builder builder(FromSourceLocation context) { return new Builder(context); } - private static List parse(String path) throws InnerParseError { + /** + * Parses the path argument to getAttr. + * + * @param path path argument in the form `a.b[5]` + * @param sourceLocation Source location for tracking errors + * @return List of parsed `Part`s + */ + private static List parse(String path, FromSourceLocation sourceLocation) { String[] components = path.split("\\."); List result = new ArrayList<>(); for (String component : components) { @@ -67,83 +68,63 @@ private static List parse(String path) throws InnerParseError { int slicePartIndex = component.indexOf("["); String slicePart = component.substring(slicePartIndex); if (!slicePart.endsWith("]")) { - throw new InnerParseError("Invalid path component: %s. Must end with `]`"); + throw new InvalidRulesException("Invalid path component: %s. Must end with `]`", + sourceLocation); } try { String number = slicePart.substring(1, slicePart.length() - 1); int slice = Integer.parseInt(number); if (slice < 0) { - throw new InnerParseError("Invalid path component: slice index must be >= 0"); + throw new InvalidRulesException("Invalid path component: slice index must be >= 0", + sourceLocation); } result.add(Part.Key.of(component.substring(0, slicePartIndex))); result.add(new Part.Index(slice)); } catch (NumberFormatException ex) { - throw new InnerParseError(String.format("%s could not be parsed as a number", slicePart)); + throw new InvalidRulesException(String.format("%s could not be parsed as a number", slicePart), + sourceLocation); } } else { result.add(Part.Key.of(component)); } } if (result.isEmpty()) { - throw new InnerParseError("Invalid argument to GetAttr: path may not be empty"); + throw new InvalidRulesException("Invalid argument to GetAttr: path may not be empty", sourceLocation); } return result; } - @Override - public Value eval(Scope scope) { - Value root = target().eval(scope); - List path = null; - try { - path = path(); - } catch (InnerParseError e) { - throw new RuntimeException(e); - } + public Value eval(Value target) { + Value root = target; + List path = getPath(); for (Part part : path) { root = part.eval(root); } return root; } - public Expr target() { - return expectTwoArgs().left; + public Expr getTarget() { + return target; } - public List path() throws InnerParseError { - Expr right = expectTwoArgs().right; - if (right instanceof Literal) { - Literal path = (Literal) right; - return parse(path.expectLiteralString()); - } else { - throw new SourceException(String.format("second argument must be a string literal (%s, %s)", - right.getClass(), right), right); - } + public List getPath() { + return path; } @Override - public T acceptFnVisitor(FnVisitor visitor) { - return visitor.visitGetAttr(this); + public String toString() { + return target + "#" + unparse(); } @Override - public String toString() { - StringBuilder out = new StringBuilder(); - out.append(target()); - try { - for (Part part : path()) { - out.append("."); - out.append(part); - } - } catch (InnerParseError e) { - throw new RuntimeException(e); - } - return out.toString(); + public R accept(ExprVisitor visitor) { + return visitor.visitGetAttr(this); } @Override - public Type typecheckLocal(Scope scope) throws InnerParseError { - Expr target = target(); - List path = new ArrayList<>(path()); + public Type typecheckLocal(Scope scope) { + Expr target = getTarget(); + List path = new ArrayList<>(getPath()); Type base = target.typecheck(scope); for (Part part : path) { @@ -155,24 +136,47 @@ public Type typecheckLocal(Scope scope) throws InnerParseError { @Override public String template() { - String target = ((Ref) this.target()).getName().asString(); - StringBuilder pathPart = new StringBuilder(); - - List partList = null; - try { - partList = path(); - } catch (InnerParseError e) { - throw new RuntimeException(e); - } - for (int i = 0; i < partList.size(); i++) { - if (i != 0) { - if (partList.get(i) instanceof Part.Key) { - pathPart.append("."); - } + String target = ((Ref) this.getTarget()).getName().asString(); + return "{" + target + "#" + unparse() + "}"; + } + + @Override + public Node toNode() { + // need to synthesize an fn-node: + // { "fn": "getAttr", "argv": [, path] } + return ObjectNode.builder() + .withMember("fn", GetAttr.ID) + .withMember("argv", ArrayNode.arrayNode(target.toNode(), StringNode.from(unparse()))).build(); + } + + private String unparse() { + StringBuilder path = new StringBuilder(); + boolean first = true; + for (Part part : getPath()) { + if (!first && part instanceof Part.Key) { + path.append("."); } - pathPart.append(partList.get(i).toString()); + first = false; + path.append(part); } - return "{" + target + "#" + pathPart + "}"; + return path.toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + GetAttr getAttr = (GetAttr) o; + return target.equals(getAttr.target) && path.equals(getAttr.path); + } + + @Override + public int hashCode() { + return Objects.hash(target, path); } public interface Part { @@ -280,7 +284,7 @@ public String toString() { } } - public static class Builder extends SourceAwareBuilder { + public static class Builder extends SourceLocationTrackingBuilder { Expr target; String path; @@ -300,7 +304,7 @@ public Builder path(String path) { @Override public GetAttr build() { - return GetAttr.fromBuilder(this); + return new GetAttr(this); } } } diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/IsSet.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/IsSet.java similarity index 76% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/IsSet.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/IsSet.java index cd489aeb6d6..cda665d3829 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/IsSet.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/IsSet.java @@ -13,15 +13,13 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.fn; +package software.amazon.smithy.rulesengine.language.syntax.fn; import software.amazon.smithy.rulesengine.language.eval.Scope; import software.amazon.smithy.rulesengine.language.eval.Type; -import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.lang.expr.Ref; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.expr.Ref; import software.amazon.smithy.rulesengine.language.visit.ExprVisitor; -import software.amazon.smithy.rulesengine.language.visit.FnVisitor; import software.amazon.smithy.utils.SmithyUnstableApi; @SmithyUnstableApi @@ -37,15 +35,6 @@ public static IsSet ofExpr(Expr expr) { return new IsSet(FnNode.ofExprs(ID, expr)); } - @Override - public T acceptFnVisitor(FnVisitor visitor) { - return visitor.visitIsSet(this); - } - - @Override - protected Value evalArg(Value arg) { - return Value.bool(!arg.isNone()); - } @Override protected Type typecheckArg(Scope scope, Type.Option arg) { @@ -66,4 +55,8 @@ public Void visitRef(Ref ref) { return Type.bool(); } + @Override + public R accept(ExprVisitor visitor) { + return visitor.visitIsSet(target()); + } } diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/LibraryFunction.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/LibraryFunction.java new file mode 100644 index 00000000000..4c4a71da6f8 --- /dev/null +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/LibraryFunction.java @@ -0,0 +1,113 @@ +/* + * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.smithy.rulesengine.language.syntax.fn; + +import static software.amazon.smithy.rulesengine.language.error.RuleError.ctx; + +import java.util.List; +import software.amazon.smithy.rulesengine.language.error.InnerParseError; +import software.amazon.smithy.rulesengine.language.eval.Scope; +import software.amazon.smithy.rulesengine.language.eval.Type; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.util.StringUtils; +import software.amazon.smithy.rulesengine.language.visit.ExprVisitor; +import software.amazon.smithy.utils.SmithyUnstableApi; + +/** + * A function ({@link Fn}) which is constructed from a {@link FunctionDefinition}. + */ +@SmithyUnstableApi +public class LibraryFunction extends Fn { + private final FunctionDefinition definition; + private final FnNode fnNode; + + public LibraryFunction(FunctionDefinition definition, FnNode fnNode) { + super(fnNode); + this.definition = definition; + this.fnNode = fnNode; + } + + public static LibraryFunction ofExprs(FunctionDefinition defn, Expr... expr) { + FnNode node = FnNode.ofExprs(defn.id(), expr); + return new LibraryFunction(defn, node); + } + + public static void checkTypeSignature(List expectedArgs, List actualArguments, Scope scope) + throws InnerParseError { + if (expectedArgs.size() != actualArguments.size()) { + throw new InnerParseError( + String.format( + "Expected %s arguments but found %s", + expectedArgs.size(), + actualArguments) + ); + } + for (int i = 0; i < expectedArgs.size(); i++) { + Type expected = expectedArgs.get(i); + Type actual = actualArguments.get(i).typecheck(scope); + if (!expected.equals(actual)) { + Type optAny = Type.optional(new Type.Any()); + String hint = ""; + if (actual.isA(optAny) && !expected.isA(optAny) && actual.expectOptional().inner().equals(expected)) { + hint = String.format( + "%nhint: use `assign` in a condition or `isSet(%s)` to prove that this value is non-null", + actualArguments.get(i)); + hint = StringUtils.indent(hint, 2); + } + throw new InnerParseError( + String.format( + "Unexpected type in the %s argument: Expected %s but found %s %s", + ordinal(i + 1), expected, actual, hint) + ); + } + } + + } + + @Override + protected Type typecheckLocal(Scope scope) { + ctx(String.format("while typechecking the invocation of %s", definition.id()), this, () -> { + try { + checkTypeSignature(definition.arguments(), fnNode.getArgv(), scope); + } catch (InnerParseError e) { + throw new RuntimeException(e); + } + }); + return definition.returnType(); + } + + private static String ordinal(int arg) { + switch (arg) { + case 1: + return "first"; + case 2: + return "second"; + case 3: + return "third"; + case 4: + return "fourth"; + case 5: + return "fifth"; + default: + return String.format("%s", arg); + } + } + + @Override + public T accept(ExprVisitor visitor) { + return visitor.visitLibraryFunction(this.definition, this.fnNode.getArgv()); + } +} diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/Not.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/Not.java similarity index 79% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/Not.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/Not.java index 456fc13ae51..b0e9ccaa4a3 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/Not.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/Not.java @@ -13,15 +13,14 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.fn; +package software.amazon.smithy.rulesengine.language.syntax.fn; import static software.amazon.smithy.rulesengine.language.error.RuleError.ctx; import software.amazon.smithy.rulesengine.language.eval.Scope; import software.amazon.smithy.rulesengine.language.eval.Type; -import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.visit.FnVisitor; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.visit.ExprVisitor; import software.amazon.smithy.utils.SmithyUnstableApi; @SmithyUnstableApi @@ -41,18 +40,13 @@ public static Not ofExprs(Expr expr) { return new Not(FnNode.ofExprs(ID, expr)); } - @Override - public T acceptFnVisitor(FnVisitor visitor) { - return visitor.visitNot(this); - } - public Expr target() { return expectOneArg(); } @Override - protected Value evalArg(Value arg) { - return Value.bool(!arg.expectBool()); + public R accept(ExprVisitor visitor) { + return visitor.visitNot(target()); } @Override diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/SingleArgFn.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/SingleArgFn.java similarity index 76% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/SingleArgFn.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/SingleArgFn.java index 52c4a7f7f82..44c1767420a 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/fn/SingleArgFn.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/fn/SingleArgFn.java @@ -13,22 +13,21 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.fn; +package software.amazon.smithy.rulesengine.language.syntax.fn; import static software.amazon.smithy.rulesengine.language.error.RuleError.ctx; import software.amazon.smithy.model.SourceException; import software.amazon.smithy.rulesengine.language.eval.Scope; import software.amazon.smithy.rulesengine.language.eval.Type; -import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; import software.amazon.smithy.utils.SmithyUnstableApi; @SmithyUnstableApi -public abstract class SingleArgFn extends Fn { - T expectedType; +abstract class SingleArgFn extends Fn { + final T expectedType; - public SingleArgFn(FnNode fnNode, T expectedType) { + SingleArgFn(FnNode fnNode, T expectedType) { super(fnNode); this.expectedType = expectedType; } @@ -37,13 +36,6 @@ public Expr target() { return expectOneArg(); } - @Override - public Value eval(Scope scope) { - return evalArg(expectOneArg().eval(scope)); - } - - protected abstract Value evalArg(Value arg); - @Override protected Type typecheckLocal(Scope scope) { return ctx("while typechecking " + this.fnNode.getId(), this, () -> { diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/parameters/Builtins.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/Builtins.java similarity index 99% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/parameters/Builtins.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/Builtins.java index f4d94003329..ab52c732cee 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/parameters/Builtins.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/Builtins.java @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.parameters; +package software.amazon.smithy.rulesengine.language.syntax.parameters; import java.util.List; import software.amazon.smithy.rulesengine.language.eval.Value; diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/parameters/Parameter.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/Parameter.java similarity index 95% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/parameters/Parameter.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/Parameter.java index 1e89cae29e2..25b502222ce 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/parameters/Parameter.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/Parameter.java @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.parameters; +package software.amazon.smithy.rulesengine.language.syntax.parameters; import java.util.Arrays; import java.util.Objects; @@ -25,13 +25,14 @@ import software.amazon.smithy.model.node.ObjectNode; import software.amazon.smithy.model.node.StringNode; import software.amazon.smithy.model.node.ToNode; -import software.amazon.smithy.rulesengine.language.SourceAwareBuilder; import software.amazon.smithy.rulesengine.language.error.RuleError; import software.amazon.smithy.rulesengine.language.eval.Type; import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.Identifier; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.lang.fn.BooleanEquals; +import software.amazon.smithy.rulesengine.language.stdlib.BooleanEquals; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.fn.Fn; +import software.amazon.smithy.rulesengine.language.util.SourceLocationTrackingBuilder; import software.amazon.smithy.utils.SmithyBuilder; import software.amazon.smithy.utils.SmithyUnstableApi; import software.amazon.smithy.utils.ToSmithyBuilder; @@ -129,7 +130,7 @@ public ParameterType getType() { } public Type toType() { - Type out = null; + Type out; switch (this.type) { case STRING: @@ -247,11 +248,11 @@ public Expr expr() { return Expr.ref(this.name, SourceLocation.none()); } - public BooleanEquals eq(boolean b) { + public Fn eq(boolean b) { return BooleanEquals.fromParam(this, Expr.of(b)); } - public BooleanEquals eq(Expr e) { + public Fn eq(Expr e) { return BooleanEquals.fromParam(this, e); } @@ -327,7 +328,7 @@ public String toString() { } - public static final class Builder extends SourceAwareBuilder { + public static final class Builder extends SourceLocationTrackingBuilder { private ParameterType type; private Identifier name; private String builtIn; diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/parameters/ParameterReference.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/ParameterReference.java similarity index 97% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/parameters/ParameterReference.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/ParameterReference.java index 34503bb6a24..6e1f78b9e94 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/parameters/ParameterReference.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/ParameterReference.java @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.parameters; +package software.amazon.smithy.rulesengine.language.syntax.parameters; import java.util.Objects; import java.util.Optional; diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/parameters/ParameterType.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/ParameterType.java similarity index 96% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/parameters/ParameterType.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/ParameterType.java index dfcdebe771b..353718126ea 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/parameters/ParameterType.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/ParameterType.java @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.parameters; +package software.amazon.smithy.rulesengine.language.syntax.parameters; import software.amazon.smithy.model.SourceException; import software.amazon.smithy.model.node.StringNode; diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/parameters/Parameters.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/Parameters.java similarity index 93% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/parameters/Parameters.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/Parameters.java index f8151f8b8c9..1124335619a 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/parameters/Parameters.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/Parameters.java @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.parameters; +package software.amazon.smithy.rulesengine.language.syntax.parameters; import static software.amazon.smithy.rulesengine.language.error.RuleError.ctx; @@ -28,11 +28,11 @@ import software.amazon.smithy.model.node.ObjectNode; import software.amazon.smithy.model.node.StringNode; import software.amazon.smithy.model.node.ToNode; -import software.amazon.smithy.rulesengine.language.SourceAwareBuilder; import software.amazon.smithy.rulesengine.language.error.RuleError; import software.amazon.smithy.rulesengine.language.eval.Scope; import software.amazon.smithy.rulesengine.language.eval.Type; -import software.amazon.smithy.rulesengine.language.lang.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.util.SourceLocationTrackingBuilder; import software.amazon.smithy.utils.SmithyBuilder; import software.amazon.smithy.utils.SmithyUnstableApi; import software.amazon.smithy.utils.ToSmithyBuilder; @@ -123,7 +123,7 @@ public Node toNode() { return params.build(); } - public static class Builder extends SourceAwareBuilder { + public static class Builder extends SourceLocationTrackingBuilder { private final List parameters = new ArrayList<>(); public Builder(FromSourceLocation sourceLocation) { diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/parameters/ToParameterReference.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/ToParameterReference.java similarity index 91% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/parameters/ToParameterReference.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/ToParameterReference.java index 5cb40611dd0..4e6afd068a7 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/parameters/ToParameterReference.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/parameters/ToParameterReference.java @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.parameters; +package software.amazon.smithy.rulesengine.language.syntax.parameters; import software.amazon.smithy.utils.SmithyUnstableApi; diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/rule/Condition.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/Condition.java similarity index 80% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/rule/Condition.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/Condition.java index e7583c827df..44268498b2d 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/rule/Condition.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/Condition.java @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.rule; +package software.amazon.smithy.rulesengine.language.syntax.rule; import java.util.Objects; import java.util.Optional; @@ -24,21 +24,18 @@ import software.amazon.smithy.model.node.ObjectNode; import software.amazon.smithy.model.node.ToNode; import software.amazon.smithy.rulesengine.IntoSelf; -import software.amazon.smithy.rulesengine.language.SourceAwareBuilder; -import software.amazon.smithy.rulesengine.language.eval.Eval; import software.amazon.smithy.rulesengine.language.eval.Scope; import software.amazon.smithy.rulesengine.language.eval.Type; import software.amazon.smithy.rulesengine.language.eval.Typecheck; -import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.Identifier; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.lang.fn.Fn; -import software.amazon.smithy.rulesengine.language.lang.fn.FnNode; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.fn.FnNode; +import software.amazon.smithy.rulesengine.language.util.SourceLocationHelpers; import software.amazon.smithy.utils.SmithyBuilder; import software.amazon.smithy.utils.SmithyUnstableApi; @SmithyUnstableApi -public final class Condition implements Typecheck, Eval, FromSourceLocation, ToNode, IntoSelf { +public final class Condition implements Typecheck, FromSourceLocation, ToNode, IntoSelf { public static final String ASSIGN = "assign"; private final Expr fn; private final Identifier result; @@ -50,7 +47,7 @@ private Condition(Builder builder) { public static Condition fromNode(Node node) { ObjectNode on = node.expectObjectNode("condition must be an object node"); - Fn fn = FnNode.fromNode(on).validate(); + Expr fn = FnNode.fromNode(on).validate(); Optional result = on.getStringMember(ASSIGN).map(Identifier::of); Builder builder = new Builder(); result.ifPresent(builder::result); @@ -111,15 +108,6 @@ public String toString() { return sb.toString(); } - @Override - public Value eval(Scope scope) { - Value value = this.fn.eval(scope); - if (!value.isNone()) { - this.getResult().ifPresent(res -> scope.insert(res, value)); - } - return value; - } - @Override public Node toNode() { ObjectNode.Builder conditionNode = fn.toNode().expectObjectNode().toBuilder(); @@ -131,7 +119,7 @@ public Node toNode() { public Expr expr() { if (this.getResult().isPresent()) { - return Expr.ref(this.getResult().get(), SourceAwareBuilder.javaLocation()); + return Expr.ref(this.getResult().get(), SourceLocationHelpers.javaLocation()); } else { throw new RuntimeException("Cannot generate expr from a condition without a result"); } @@ -139,10 +127,10 @@ public Expr expr() { public static class Builder implements SmithyBuilder { - private Fn fn; + private Expr fn; private Identifier result; - public Builder fn(Fn fn) { + public Builder fn(Expr fn) { this.fn = fn; return this; } diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/rule/EndpointRule.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/EndpointRule.java similarity index 97% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/rule/EndpointRule.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/EndpointRule.java index 627adeb292d..7704b918b29 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/rule/EndpointRule.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/EndpointRule.java @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.rule; +package software.amazon.smithy.rulesengine.language.syntax.rule; import static software.amazon.smithy.rulesengine.language.error.RuleError.ctx; diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/rule/ErrorRule.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/ErrorRule.java similarity index 94% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/rule/ErrorRule.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/ErrorRule.java index 91dddc0cf8f..0d9153b7f2b 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/rule/ErrorRule.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/ErrorRule.java @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.rule; +package software.amazon.smithy.rulesengine.language.syntax.rule; import static software.amazon.smithy.rulesengine.language.error.RuleError.ctx; @@ -21,7 +21,7 @@ import software.amazon.smithy.model.node.ObjectNode; import software.amazon.smithy.rulesengine.language.eval.Scope; import software.amazon.smithy.rulesengine.language.eval.Type; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; import software.amazon.smithy.rulesengine.language.util.StringUtils; import software.amazon.smithy.rulesengine.language.visit.RuleValueVisitor; import software.amazon.smithy.utils.SmithyUnstableApi; diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/rule/Rule.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/Rule.java similarity index 94% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/rule/Rule.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/Rule.java index 81499ba2eba..b059918ff30 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/rule/Rule.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/Rule.java @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.rule; +package software.amazon.smithy.rulesengine.language.syntax.rule; import static software.amazon.smithy.rulesengine.language.error.RuleError.ctx; import static software.amazon.smithy.rulesengine.language.util.StringUtils.indent; @@ -34,12 +34,12 @@ import software.amazon.smithy.model.node.ToNode; import software.amazon.smithy.rulesengine.Into; import software.amazon.smithy.rulesengine.language.Endpoint; -import software.amazon.smithy.rulesengine.language.SourceAwareBuilder; import software.amazon.smithy.rulesengine.language.eval.Scope; import software.amazon.smithy.rulesengine.language.eval.Type; import software.amazon.smithy.rulesengine.language.eval.Typecheck; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.lang.expr.Literal; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.expr.Literal; +import software.amazon.smithy.rulesengine.language.util.SourceLocationHelpers; import software.amazon.smithy.rulesengine.language.visit.RuleValueVisitor; import software.amazon.smithy.utils.SmithyUnstableApi; @@ -244,7 +244,7 @@ public Builder description(String description) { */ @SafeVarargs public final Builder errorOrElse(String error, Into... condition) { - Builder next = new Builder(SourceAwareBuilder.javaLocation()); + Builder next = new Builder(SourceLocationHelpers.javaLocation()); next.onBuild = (Rule r) -> this.treeRule( Rule.builder().conditions(condition).error(error), r @@ -264,7 +264,7 @@ public final Builder errorOrElse(String error, Into... condition) { * @return a new builder to attach subsequent rules to */ public Builder validateOrElse(Into condition, String error) { - Builder next = new Builder(SourceAwareBuilder.javaLocation()); + Builder next = new Builder(SourceLocationHelpers.javaLocation()); next.onBuild = (Rule r) -> this.treeRule( Rule.builder().conditions(condition).treeRule(r), Rule.builder().error(error) @@ -281,10 +281,10 @@ public Builder validateOrElse(Into condition, String error) { * * @param condition a coercible {@link Condition} * @param error an error description if the condition is not matched - * @returna new builder to attach subsequent rules to + * @return new builder to attach subsequent rules to */ public Builder validateOrElse(String error, Into... condition) { - Builder next = new Builder(SourceAwareBuilder.javaLocation()); + Builder next = new Builder(SourceLocationHelpers.javaLocation()); next.onBuild = (Rule r) -> this.treeRule( Rule.builder().conditions(condition).treeRule(r), Rule.builder().error(error) diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/rule/TreeRule.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/TreeRule.java similarity index 97% rename from smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/rule/TreeRule.java rename to smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/TreeRule.java index fb2a2aec6d0..b2c2146bf84 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/lang/rule/TreeRule.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/syntax/rule/TreeRule.java @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.rule; +package software.amazon.smithy.rulesengine.language.syntax.rule; import static software.amazon.smithy.rulesengine.language.error.RuleError.ctx; diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/util/MandatorySourceLocation.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/util/MandatorySourceLocation.java new file mode 100644 index 00000000000..6439a6b2694 --- /dev/null +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/util/MandatorySourceLocation.java @@ -0,0 +1,38 @@ +/* + * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.smithy.rulesengine.language.util; + +import java.util.Objects; +import software.amazon.smithy.model.FromSourceLocation; +import software.amazon.smithy.model.SourceLocation; +import software.amazon.smithy.utils.SmithyInternalApi; + +/** + * Abstract class that mandates that all child classes provide a source location. + */ +@SmithyInternalApi +public abstract class MandatorySourceLocation implements FromSourceLocation { + private final SourceLocation sourceLocation; + + public MandatorySourceLocation(FromSourceLocation sourceLocation) { + this.sourceLocation = Objects.requireNonNull(sourceLocation.getSourceLocation()); + } + + @Override + public SourceLocation getSourceLocation() { + return sourceLocation; + } +} diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/util/PathFinder.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/util/PathFinder.java index 2acf24f038b..58e95220c52 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/util/PathFinder.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/util/PathFinder.java @@ -22,8 +22,8 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import software.amazon.smithy.rulesengine.language.EndpointRuleset; -import software.amazon.smithy.rulesengine.language.lang.rule.Condition; -import software.amazon.smithy.rulesengine.language.lang.rule.Rule; +import software.amazon.smithy.rulesengine.language.syntax.rule.Condition; +import software.amazon.smithy.rulesengine.language.syntax.rule.Rule; import software.amazon.smithy.rulesengine.language.visit.DefaultVisitor; import software.amazon.smithy.utils.SmithyUnstableApi; diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/util/SourceLocationHelpers.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/util/SourceLocationHelpers.java new file mode 100644 index 00000000000..ca006f98433 --- /dev/null +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/util/SourceLocationHelpers.java @@ -0,0 +1,84 @@ +/* + * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.smithy.rulesengine.language.util; + +import software.amazon.smithy.model.SourceLocation; +import software.amazon.smithy.utils.SmithyInternalApi; + +@SmithyInternalApi +public final class SourceLocationHelpers { + private SourceLocationHelpers() { + } + + /** + * Returns the source code location of the caller. This is very helpful when determining where rules generated + * from Java-based builders originated. + * + *

Library-local and JDK stack frames are discarded. If no relevant location can be found, + * `SourceLocation.none()` is returned. + * + * @return The SourceLocation. + */ + public static SourceLocation javaLocation() { + for (StackTraceElement e : Thread.currentThread().getStackTrace()) { + if (isStackTraceRelevant(e)) { + if (e.getFileName() == null) { + return SourceLocation.none(); + } + return new SourceLocation(e.getFileName(), e.getLineNumber(), 0); + } + } + return SourceLocation.none(); + } + + /** + * Prints a source location in "stack trace form": `filename:linenumber`. + * @param sourceLocation Source location to print + * @return formatted source location + */ + public static String stackTraceForm(SourceLocation sourceLocation) { + if (sourceLocation == SourceLocation.NONE) { + return "N/A"; + } + StringBuilder sb = new StringBuilder(); + if (sourceLocation.getFilename() != null) { + sb.append(sourceLocation.getFilename()); + } + if (sourceLocation.getLine() != 0) { + sb.append(":").append(sourceLocation.getLine()); + } + /* column is ignored in stack trace form */ + return sb.toString(); + } + + /** + * Tests if the given {@code StackTraceElement} is relevant for a comment + * used when writing debug information before calls to write. + * + *

The implementation filters out all methods in "java.*", + * and `software.amazon.smithy.rulesengine` + * + * @param e StackTraceElement to test. + * @return Returns true if this element should be in a comment. + */ + static boolean isStackTraceRelevant(StackTraceElement e) { + String normalized = e.getClassName().replace("$", "."); + return !normalized.startsWith("java.") + && !normalized.startsWith("jdk.") + && !normalized.startsWith(SourceLocationHelpers.class.getCanonicalName()) + && !normalized.startsWith("software.amazon.smithy.rulesengine"); + } +} diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/util/SourceLocationTrackingBuilder.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/util/SourceLocationTrackingBuilder.java new file mode 100644 index 00000000000..1b9f61c7d34 --- /dev/null +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/util/SourceLocationTrackingBuilder.java @@ -0,0 +1,56 @@ +/* + * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.smithy.rulesengine.language.util; + +import static software.amazon.smithy.rulesengine.language.util.SourceLocationHelpers.javaLocation; + +import software.amazon.smithy.model.FromSourceLocation; +import software.amazon.smithy.model.SourceLocation; +import software.amazon.smithy.utils.SmithyBuilder; +import software.amazon.smithy.utils.SmithyUnstableApi; + +/** + * Builder which also tracks sourceLocation of inputs. If no source location is provided, the source location defaults + * to the Java file/line number of the caller. + * @param Type of the builder + * @param Type of the type that is built + */ +@SmithyUnstableApi +public abstract class SourceLocationTrackingBuilder, T> + implements SmithyBuilder, FromSourceLocation { + + protected SourceLocation sourceLocation; + + public SourceLocationTrackingBuilder(FromSourceLocation sourceLocation) { + if (sourceLocation.getSourceLocation() == SourceLocation.NONE) { + this.sourceLocation = javaLocation(); + } else { + this.sourceLocation = sourceLocation.getSourceLocation(); + } + } + + @Override + public SourceLocation getSourceLocation() { + return sourceLocation; + } + + @SuppressWarnings("unchecked") + public B sourceLocation(SourceLocation sourceLocation) { + this.sourceLocation = sourceLocation; + return (B) this; + } + +} diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/DefaultVisitor.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/DefaultVisitor.java index 3306ca4f2a3..313fdd60278 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/DefaultVisitor.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/DefaultVisitor.java @@ -17,26 +17,16 @@ import java.util.List; import software.amazon.smithy.rulesengine.language.Endpoint; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.lang.expr.Literal; -import software.amazon.smithy.rulesengine.language.lang.expr.Ref; -import software.amazon.smithy.rulesengine.language.lang.fn.BooleanEquals; -import software.amazon.smithy.rulesengine.language.lang.fn.Fn; -import software.amazon.smithy.rulesengine.language.lang.fn.GetAttr; -import software.amazon.smithy.rulesengine.language.lang.fn.IsSet; -import software.amazon.smithy.rulesengine.language.lang.fn.IsValidHostLabel; -import software.amazon.smithy.rulesengine.language.lang.fn.Not; -import software.amazon.smithy.rulesengine.language.lang.fn.ParseArn; -import software.amazon.smithy.rulesengine.language.lang.fn.ParseUrl; -import software.amazon.smithy.rulesengine.language.lang.fn.PartitionFn; -import software.amazon.smithy.rulesengine.language.lang.fn.StringEquals; -import software.amazon.smithy.rulesengine.language.lang.fn.Substring; -import software.amazon.smithy.rulesengine.language.lang.fn.UriEncode; -import software.amazon.smithy.rulesengine.language.lang.rule.Rule; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.expr.Literal; +import software.amazon.smithy.rulesengine.language.syntax.expr.Ref; +import software.amazon.smithy.rulesengine.language.syntax.fn.FunctionDefinition; +import software.amazon.smithy.rulesengine.language.syntax.fn.GetAttr; +import software.amazon.smithy.rulesengine.language.syntax.rule.Rule; import software.amazon.smithy.utils.SmithyUnstableApi; @SmithyUnstableApi -public abstract class DefaultVisitor implements RuleValueVisitor, ExprVisitor, FnVisitor { +public abstract class DefaultVisitor implements RuleValueVisitor, ExprVisitor { public abstract R getDefault(); @Override @@ -50,63 +40,31 @@ public R visitRef(Ref ref) { } @Override - public R visitFn(Fn fn) { + public R visitIsSet(Expr fn) { return getDefault(); } @Override - public R visitPartition(PartitionFn fn) { + public R visitNot(Expr not) { return getDefault(); } @Override - public R visitParseArn(ParseArn fn) { - return getDefault(); - } - - - @Override - public R visitIsValidHostLabel(IsValidHostLabel fn) { - return getDefault(); - } - - @Override - public R visitBoolEquals(BooleanEquals fn) { - return getDefault(); - } - - @Override - public R visitStringEquals(StringEquals fn) { + public R visitBoolEquals(Expr left, Expr right) { return getDefault(); } @Override - public R visitIsSet(IsSet fn) { + public R visitStringEquals(Expr left, Expr right) { return getDefault(); } - @Override - public R visitNot(Not not) { - return getDefault(); - } - - @Override public R visitGetAttr(GetAttr getAttr) { return getDefault(); } @Override - public R visitParseUrl(ParseUrl parseUrl) { - return getDefault(); - } - - @Override - public R visitSubstring(Substring substring) { - return getDefault(); - } - - @Override - public R visitUriEncode(UriEncode fn) { + public R visitLibraryFunction(FunctionDefinition fn, List args) { return getDefault(); } diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/ExprVisitor.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/ExprVisitor.java index a6d963606f2..7518a8a8916 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/ExprVisitor.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/ExprVisitor.java @@ -15,9 +15,12 @@ package software.amazon.smithy.rulesengine.language.visit; -import software.amazon.smithy.rulesengine.language.lang.expr.Literal; -import software.amazon.smithy.rulesengine.language.lang.expr.Ref; -import software.amazon.smithy.rulesengine.language.lang.fn.Fn; +import java.util.List; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.expr.Literal; +import software.amazon.smithy.rulesengine.language.syntax.expr.Ref; +import software.amazon.smithy.rulesengine.language.syntax.fn.FunctionDefinition; +import software.amazon.smithy.rulesengine.language.syntax.fn.GetAttr; import software.amazon.smithy.utils.SmithyUnstableApi; @SmithyUnstableApi @@ -26,7 +29,17 @@ public interface ExprVisitor { R visitRef(Ref ref); - R visitFn(Fn fn); + R visitGetAttr(GetAttr getAttr); + + R visitIsSet(Expr fn); + + R visitNot(Expr not); + + R visitBoolEquals(Expr left, Expr right); + + R visitStringEquals(Expr left, Expr right); + + R visitLibraryFunction(FunctionDefinition fn, List args); abstract class Default implements ExprVisitor { public abstract R getDefault(); @@ -41,8 +54,32 @@ public R visitRef(Ref ref) { return getDefault(); } + public R visitGetAttr(GetAttr getAttr) { + return getDefault(); + } + + @Override + public R visitIsSet(Expr fn) { + return getDefault(); + } + + @Override + public R visitNot(Expr not) { + return getDefault(); + } + + @Override + public R visitBoolEquals(Expr left, Expr right) { + return getDefault(); + } + + @Override + public R visitStringEquals(Expr left, Expr right) { + return getDefault(); + } + @Override - public R visitFn(Fn fn) { + public R visitLibraryFunction(FunctionDefinition fn, List args) { return getDefault(); } } diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/FnVisitor.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/FnVisitor.java deleted file mode 100644 index e4198ecd18f..00000000000 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/FnVisitor.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package software.amazon.smithy.rulesengine.language.visit; - -import software.amazon.smithy.rulesengine.language.lang.fn.BooleanEquals; -import software.amazon.smithy.rulesengine.language.lang.fn.GetAttr; -import software.amazon.smithy.rulesengine.language.lang.fn.IsSet; -import software.amazon.smithy.rulesengine.language.lang.fn.IsValidHostLabel; -import software.amazon.smithy.rulesengine.language.lang.fn.Not; -import software.amazon.smithy.rulesengine.language.lang.fn.ParseArn; -import software.amazon.smithy.rulesengine.language.lang.fn.ParseUrl; -import software.amazon.smithy.rulesengine.language.lang.fn.PartitionFn; -import software.amazon.smithy.rulesengine.language.lang.fn.StringEquals; -import software.amazon.smithy.rulesengine.language.lang.fn.Substring; -import software.amazon.smithy.rulesengine.language.lang.fn.UriEncode; -import software.amazon.smithy.utils.SmithyUnstableApi; - -@SmithyUnstableApi -public interface FnVisitor { - R visitPartition(PartitionFn fn); - - R visitParseArn(ParseArn fn); - - R visitIsValidHostLabel(IsValidHostLabel fn); - - R visitBoolEquals(BooleanEquals fn); - - R visitStringEquals(StringEquals fn); - - R visitIsSet(IsSet fn); - - R visitNot(Not not); - - R visitGetAttr(GetAttr getAttr); - - R visitParseUrl(ParseUrl parseUrl); - - R visitSubstring(Substring substring); - - R visitUriEncode(UriEncode fn); -} diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/RuleValueVisitor.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/RuleValueVisitor.java index 59a8772ee91..e3e85629135 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/RuleValueVisitor.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/RuleValueVisitor.java @@ -17,8 +17,8 @@ import java.util.List; import software.amazon.smithy.rulesengine.language.Endpoint; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.lang.rule.Rule; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.rule.Rule; import software.amazon.smithy.utils.SmithyUnstableApi; /** diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/TemplateVisitor.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/TemplateVisitor.java index c3c27fe9efa..5130521b522 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/TemplateVisitor.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/TemplateVisitor.java @@ -15,7 +15,7 @@ package software.amazon.smithy.rulesengine.language.visit; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; import software.amazon.smithy.utils.SmithyUnstableApi; /** diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/TraversingVisitor.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/TraversingVisitor.java index 8b058f460e5..d0a6785a1d5 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/TraversingVisitor.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/visit/TraversingVisitor.java @@ -19,10 +19,9 @@ import java.util.stream.Stream; import software.amazon.smithy.rulesengine.language.Endpoint; import software.amazon.smithy.rulesengine.language.EndpointRuleset; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.lang.fn.Fn; -import software.amazon.smithy.rulesengine.language.lang.rule.Condition; -import software.amazon.smithy.rulesengine.language.lang.rule.Rule; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.rule.Condition; +import software.amazon.smithy.rulesengine.language.syntax.rule.Rule; import software.amazon.smithy.utils.SmithyUnstableApi; @SmithyUnstableApi @@ -43,11 +42,6 @@ public Stream getDefault() { return Stream.empty(); } - @Override - public Stream visitFn(Fn fn) { - return fn.acceptFnVisitor(this); - } - @Override public Stream visitTreeRule(List rules) { return rules.stream().flatMap(this::handleRule); diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/validators/AuthSchemesValidator.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/validators/AuthSchemesValidator.java index 4130e872d7a..8694ba13e3b 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/validators/AuthSchemesValidator.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/validators/AuthSchemesValidator.java @@ -24,8 +24,8 @@ import software.amazon.smithy.model.SourceLocation; import software.amazon.smithy.rulesengine.language.Endpoint; import software.amazon.smithy.rulesengine.language.EndpointRuleset; -import software.amazon.smithy.rulesengine.language.lang.Identifier; -import software.amazon.smithy.rulesengine.language.lang.expr.Literal; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.expr.Literal; import software.amazon.smithy.rulesengine.language.visit.TraversingVisitor; import software.amazon.smithy.utils.ListUtils; import software.amazon.smithy.utils.SmithyUnstableApi; diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/validators/BuiltInsValidator.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/validators/BuiltInsValidator.java index 139cec4fff4..0e57409c433 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/validators/BuiltInsValidator.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/validators/BuiltInsValidator.java @@ -21,7 +21,7 @@ import java.util.stream.Stream; import software.amazon.smithy.model.FromSourceLocation; import software.amazon.smithy.rulesengine.language.EndpointRuleset; -import software.amazon.smithy.rulesengine.language.lang.parameters.Builtins; +import software.amazon.smithy.rulesengine.language.syntax.parameters.Builtins; import software.amazon.smithy.rulesengine.traits.EndpointTestsTrait; import software.amazon.smithy.utils.SmithyUnstableApi; diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/validators/ParametersValidator.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/validators/ParametersValidator.java index 686524c4d5f..40ee0a14075 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/validators/ParametersValidator.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/validators/ParametersValidator.java @@ -31,8 +31,8 @@ import software.amazon.smithy.model.shapes.StructureShape; import software.amazon.smithy.rulesengine.language.EndpointRuleset; import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.parameters.Parameter; -import software.amazon.smithy.rulesengine.language.lang.parameters.ParameterType; +import software.amazon.smithy.rulesengine.language.syntax.parameters.Parameter; +import software.amazon.smithy.rulesengine.language.syntax.parameters.ParameterType; import software.amazon.smithy.rulesengine.traits.ClientContextParamsTrait; import software.amazon.smithy.rulesengine.traits.ContextParamTrait; import software.amazon.smithy.rulesengine.traits.EndpointTestsTrait; diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/validators/ValidateUriScheme.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/validators/ValidateUriScheme.java index 99a90bd2595..677190b6923 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/validators/ValidateUriScheme.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/validators/ValidateUriScheme.java @@ -19,9 +19,9 @@ import java.util.Map; import java.util.stream.Stream; import software.amazon.smithy.rulesengine.language.Endpoint; -import software.amazon.smithy.rulesengine.language.lang.Identifier; -import software.amazon.smithy.rulesengine.language.lang.expr.Literal; -import software.amazon.smithy.rulesengine.language.lang.expr.Template; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.expr.Literal; +import software.amazon.smithy.rulesengine.language.syntax.expr.Template; import software.amazon.smithy.rulesengine.language.visit.TraversingVisitor; import software.amazon.smithy.utils.SmithyUnstableApi; diff --git a/smithy-rules-engine/src/main/resources/META-INF/services/software.amazon.smithy.rulesengine.language.lang.fn.partition.PartitionDataProvider b/smithy-rules-engine/src/main/resources/META-INF/services/software.amazon.smithy.rulesengine.language.lang.fn.partition.PartitionDataProvider deleted file mode 100644 index f7edf11c725..00000000000 --- a/smithy-rules-engine/src/main/resources/META-INF/services/software.amazon.smithy.rulesengine.language.lang.fn.partition.PartitionDataProvider +++ /dev/null @@ -1 +0,0 @@ -software.amazon.smithy.rulesengine.language.lang.fn.partition.DefaultPartitionDataProvider diff --git a/smithy-rules-engine/src/main/resources/META-INF/services/software.amazon.smithy.rulesengine.language.stdlib.partition.PartitionDataProvider b/smithy-rules-engine/src/main/resources/META-INF/services/software.amazon.smithy.rulesengine.language.stdlib.partition.PartitionDataProvider new file mode 100644 index 00000000000..c2eeffa5b00 --- /dev/null +++ b/smithy-rules-engine/src/main/resources/META-INF/services/software.amazon.smithy.rulesengine.language.stdlib.partition.PartitionDataProvider @@ -0,0 +1 @@ +software.amazon.smithy.rulesengine.language.stdlib.partition.DefaultPartitionDataProvider diff --git a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/analysis/CoverageCheckerTest.java b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/analysis/CoverageCheckerTest.java index f746e372766..a6c088c1508 100644 --- a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/analysis/CoverageCheckerTest.java +++ b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/analysis/CoverageCheckerTest.java @@ -20,7 +20,7 @@ import java.util.stream.Collectors; import org.junit.jupiter.api.Test; import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; import software.amazon.smithy.rulesengine.testutil.TestDiscovery; import software.amazon.smithy.utils.MapUtils; diff --git a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/EndpointRulesetTest.java b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/EndpointRulesetTest.java index 1cdb02db0d5..2a778fe5169 100644 --- a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/EndpointRulesetTest.java +++ b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/EndpointRulesetTest.java @@ -26,12 +26,12 @@ import software.amazon.smithy.rulesengine.language.eval.RuleEngine; import software.amazon.smithy.rulesengine.language.eval.Scope; import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.Identifier; -import software.amazon.smithy.rulesengine.language.lang.expr.Literal; -import software.amazon.smithy.rulesengine.language.lang.parameters.Parameter; -import software.amazon.smithy.rulesengine.language.lang.parameters.ParameterType; -import software.amazon.smithy.rulesengine.language.lang.parameters.Parameters; -import software.amazon.smithy.rulesengine.language.lang.rule.Rule; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.expr.Literal; +import software.amazon.smithy.rulesengine.language.syntax.parameters.Parameter; +import software.amazon.smithy.rulesengine.language.syntax.parameters.ParameterType; +import software.amazon.smithy.rulesengine.language.syntax.parameters.Parameters; +import software.amazon.smithy.rulesengine.language.syntax.rule.Rule; import software.amazon.smithy.utils.MapUtils; class EndpointRulesetTest { diff --git a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/IntegrationTest.java b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/IntegrationTest.java index 1ee6be43167..bf4b0f196e8 100644 --- a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/IntegrationTest.java +++ b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/IntegrationTest.java @@ -121,10 +121,12 @@ void executeTestSuite(TestDiscovery.RulesTestCase testcase) { @ParameterizedTest @MethodSource("invalidTestCases") void checkInvalidRules(ValidationTestCase validationTestCase) throws IOException { - assertThrows(RuleError.class, () -> { + RuleError error = assertThrows(RuleError.class, () -> { EndpointRuleset ruleset = EndpointRuleset.fromNode(validationTestCase.contents()); ruleset.typecheck(new Scope<>()); }); + //validationTestCase.overrideComments(error.toString()); + assertEquals(validationTestCase.comments().trim(), error.toString().trim()); } public static final class ValidationTestCase { diff --git a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/ParametersValidationTest.java b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/ParametersValidationTest.java index d769f4fdcc8..6da05bdbe5c 100644 --- a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/ParametersValidationTest.java +++ b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/ParametersValidationTest.java @@ -29,8 +29,8 @@ import software.amazon.smithy.model.node.Node; import software.amazon.smithy.model.node.ObjectNode; import software.amazon.smithy.model.shapes.ShapeId; -import software.amazon.smithy.rulesengine.language.lang.parameters.Parameter; -import software.amazon.smithy.rulesengine.language.lang.parameters.ParameterType; +import software.amazon.smithy.rulesengine.language.syntax.parameters.Parameter; +import software.amazon.smithy.rulesengine.language.syntax.parameters.ParameterType; import software.amazon.smithy.rulesengine.traits.EndpointTestsTrait; import software.amazon.smithy.rulesengine.validators.ParametersValidator; import software.amazon.smithy.rulesengine.validators.ValidationError; diff --git a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/eval/RuleEngineTest.java b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/eval/RuleEngineTest.java index 20affc29480..b2f7e112853 100644 --- a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/eval/RuleEngineTest.java +++ b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/eval/RuleEngineTest.java @@ -24,7 +24,7 @@ import software.amazon.smithy.model.node.Node; import software.amazon.smithy.model.node.ObjectNode; import software.amazon.smithy.rulesengine.language.EndpointRuleset; -import software.amazon.smithy.rulesengine.language.lang.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; import software.amazon.smithy.utils.MapUtils; class RuleEngineTest { diff --git a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/fn/PartitionFnTest.java b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/fn/PartitionFnTest.java index 2caa99858aa..ff25f9d57ab 100644 --- a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/fn/PartitionFnTest.java +++ b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/fn/PartitionFnTest.java @@ -23,11 +23,12 @@ import software.amazon.smithy.model.node.ArrayNode; import software.amazon.smithy.model.node.ObjectNode; import software.amazon.smithy.model.node.StringNode; +import software.amazon.smithy.rulesengine.language.eval.RuleEvaluator; import software.amazon.smithy.rulesengine.language.eval.Scope; import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.lang.fn.Fn; -import software.amazon.smithy.rulesengine.language.lang.fn.PartitionFn; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.fn.Fn; +import software.amazon.smithy.rulesengine.language.stdlib.PartitionFn; public class PartitionFnTest { @Test @@ -61,6 +62,6 @@ private Value.Record evalWithRegion(String region) { .withMember("argv", ArrayNode.arrayNode(StringNode.from(region))) .build()); - return fn.eval(new Scope<>()).expectRecord(); + return fn.accept(new RuleEvaluator()).expectRecord(); } } diff --git a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/fn/partition/ServiceLoaderTest.java b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/fn/partition/ServiceLoaderTest.java index 5b2cc39f229..72910486275 100644 --- a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/fn/partition/ServiceLoaderTest.java +++ b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/fn/partition/ServiceLoaderTest.java @@ -22,7 +22,7 @@ import java.util.Iterator; import java.util.ServiceLoader; import org.junit.jupiter.api.Test; -import software.amazon.smithy.rulesengine.language.lang.fn.partition.PartitionDataProvider; +import software.amazon.smithy.rulesengine.language.stdlib.partition.PartitionDataProvider; public class ServiceLoaderTest { @Test diff --git a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/model/PartitionsTest.java b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/model/PartitionsTest.java index b1b0d6cd70b..792c54a7b27 100644 --- a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/model/PartitionsTest.java +++ b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/model/PartitionsTest.java @@ -20,7 +20,6 @@ import org.junit.jupiter.api.Test; import software.amazon.smithy.model.node.Node; -import software.amazon.smithy.rulesengine.language.util.ResourceUtil; public class PartitionsTest { diff --git a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/lang/fn/GetAttrTest.java b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/syntax/fn/GetAttrTest.java similarity index 91% rename from smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/lang/fn/GetAttrTest.java rename to smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/syntax/fn/GetAttrTest.java index 8738d3c77fe..4c0b12c3bc4 100644 --- a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/lang/fn/GetAttrTest.java +++ b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/syntax/fn/GetAttrTest.java @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.fn; +package software.amazon.smithy.rulesengine.language.syntax.fn; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -21,7 +21,7 @@ import software.amazon.smithy.model.SourceLocation; import software.amazon.smithy.model.node.Node; import software.amazon.smithy.model.node.ObjectNode; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; class GetAttrTest { @Test diff --git a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/lang/rule/RuleTest.java b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/syntax/rule/RuleTest.java similarity index 88% rename from smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/lang/rule/RuleTest.java rename to smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/syntax/rule/RuleTest.java index 9df97252ada..340b704fa71 100644 --- a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/lang/rule/RuleTest.java +++ b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/syntax/rule/RuleTest.java @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -package software.amazon.smithy.rulesengine.language.lang.rule; +package software.amazon.smithy.rulesengine.language.syntax.rule; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -21,10 +21,10 @@ import software.amazon.smithy.rulesengine.language.EndpointRuleset; import software.amazon.smithy.rulesengine.language.eval.RuleEngine; import software.amazon.smithy.rulesengine.language.eval.Value; -import software.amazon.smithy.rulesengine.language.lang.Identifier; -import software.amazon.smithy.rulesengine.language.lang.parameters.Parameter; -import software.amazon.smithy.rulesengine.language.lang.parameters.ParameterType; -import software.amazon.smithy.rulesengine.language.lang.parameters.Parameters; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.parameters.Parameter; +import software.amazon.smithy.rulesengine.language.syntax.parameters.ParameterType; +import software.amazon.smithy.rulesengine.language.syntax.parameters.Parameters; import software.amazon.smithy.utils.MapUtils; class RuleTest { diff --git a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/value/TemplateTest.java b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/value/TemplateTest.java index ae179686a25..f0cf6529458 100644 --- a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/value/TemplateTest.java +++ b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/value/TemplateTest.java @@ -21,21 +21,21 @@ import java.util.stream.Collectors; import org.junit.jupiter.api.Test; import software.amazon.smithy.model.SourceLocation; -import software.amazon.smithy.rulesengine.language.lang.Identifier; -import software.amazon.smithy.rulesengine.language.lang.expr.Expr; -import software.amazon.smithy.rulesengine.language.lang.expr.Template; -import software.amazon.smithy.rulesengine.language.lang.fn.GetAttr; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.expr.Expr; +import software.amazon.smithy.rulesengine.language.syntax.expr.Template; +import software.amazon.smithy.rulesengine.language.syntax.fn.GetAttr; class TemplateTest { @Test void validateTemplate() { checkTemplateParts("asdf", "asdf"); - checkTemplateParts("a{B}c", "a", "{dyn B}", "c"); + checkTemplateParts("a{B}c", "a", "{B}", "c"); checkTemplateParts("a{{b}}c", "a{b}c"); - checkTemplateParts("https://{Bucket#arn-region}.{Region}.amazonaws.com", "https://", "{dyn Bucket#arn-region}", ".", "{dyn Region}", ".amazonaws.com"); - checkTemplateParts("https://{Partition#meta.dnsSuffix}", "https://", "{dyn Partition#meta.dnsSuffix}"); - checkTemplateParts("https://{ {\"ref\": \"Foo\"} }.com", "https://", "{dyn {\"ref\": \"Foo\"} }", ".com"); - checkTemplateParts("{a}b", "{dyn a}", "b"); + checkTemplateParts("https://{Bucket#arn-region}.{Region}.amazonaws.com", "https://", "{Bucket#arn-region}", ".", "{Region}", ".amazonaws.com"); + checkTemplateParts("https://{Partition#meta.dnsSuffix}", "https://", "{Partition#meta.dnsSuffix}"); + checkTemplateParts("https://{ {\"ref\": \"Foo\"} }.com", "https://", "{ {\"ref\": \"Foo\"} }", ".com"); + checkTemplateParts("{a}b", "{a}", "b"); } private void checkTemplateParts(String templateInput, String... parts) { diff --git a/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/bool-equals-unset.json5 b/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/bool-equals-unset.json5 index 46a44d7bafe..dba4a515a73 100644 --- a/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/bool-equals-unset.json5 +++ b/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/bool-equals-unset.json5 @@ -1,9 +1,7 @@ // while typechecking booleanEquals(true, UseDualStack) -// at invalid-rules/bool-equals-unset.json5:23 -// while typechecking booleanEquals(true, UseDualStack) -// while typechecking booleanEquals -// at invalid-rules/bool-equals-unset.json5:28 -// Expected boolean but found Option. hint: use `isSet` to convert Option to bool +// at invalid-rules/bool-equals-unset.json5:21 +// Unexpected type in the second argument: Expected Bool but found Option +// hint: use `assign` in a condition or `isSet(UseDualStack)` to prove that this value is non-null { "version": "1.2", "parameters": { diff --git a/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/cant-template-bool.json5 b/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/cant-template-bool.json5 index 256045458ff..c7ef534b721 100644 --- a/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/cant-template-bool.json5 +++ b/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/cant-template-bool.json5 @@ -3,8 +3,8 @@ // while typechecking the endpoint // at invalid-rules/cant-template-bool.json5:21 // while checking the URL -// while typechecking "{dyn enabled}.amazonaws.com" -// while typechecking the template `"{dyn enabled}.amazonaws.com"` +// while typechecking "{enabled}.amazonaws.com" +// while typechecking the template `"{enabled}.amazonaws.com"` // at invalid-rules/cant-template-bool.json5:22 // Expected string but found Bool { diff --git a/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/field-in-wrong-tree.json5 b/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/field-in-wrong-tree.json5 index a6261e6f237..937cbef56b1 100644 --- a/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/field-in-wrong-tree.json5 +++ b/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/field-in-wrong-tree.json5 @@ -3,11 +3,11 @@ // while typechecking the endpoint // at invalid-rules/field-in-wrong-tree.json5:42 // while checking the URL -// while typechecking "{dyn partitionResult#name}.amazonaws.com" -// while typechecking the template `"{dyn partitionResult#name}.amazonaws.com"` +// while typechecking "{partitionResult#name}.amazonaws.com" +// while typechecking the template `"{partitionResult#name}.amazonaws.com"` // at invalid-rules/field-in-wrong-tree.json5:43 -// while checking {dyn partitionResult#name} -// while typechecking partitionResult.name +// while checking {partitionResult#name} +// while typechecking partitionResult#name // while typechecking partitionResult // No field named partitionResult { diff --git a/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/invalid-slice.json5 b/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/invalid-slice.json5 index 42474bc038f..a9646e7deb1 100644 --- a/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/invalid-slice.json5 +++ b/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/invalid-slice.json5 @@ -3,8 +3,8 @@ // while typechecking the endpoint // at invalid-rules/invalid-slice.json5:39 // while checking the URL -// while typechecking "{dyn bucketArn#accountId}.{dyn bucketArn#resourceId[2]}.{dyn bucketArn#region}" -// while typechecking the template `"{dyn bucketArn#accountId}.{dyn bucketArn#resourceId[2]}.{dyn bucketArn#region}"` +// while typechecking "{bucketArn#accountId}.{bucketArn#resourceId[2]}.{bucketArn#region}" +// while typechecking the template `"{bucketArn#accountId}.{bucketArn#resourceId[2]}.{bucketArn#region}"` // at invalid-rules/invalid-slice.json5:40 // Expected string but found Option. hint: use `assign` in a condition or `isSet` to prove that this value is non-null { diff --git a/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/only-refs-coerce-isset.json5 b/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/only-refs-coerce-isset.json5 index 47b7bbcc3cb..16b2cafb592 100644 --- a/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/only-refs-coerce-isset.json5 +++ b/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/only-refs-coerce-isset.json5 @@ -9,8 +9,8 @@ // while typechecking the endpoint // at invalid-rules/only-refs-coerce-isset.json5:86 // while checking the URL -// while typechecking "https://{dyn bucketArn#resourceId[1]}-{dyn bucketArn#accountId}.{dyn bucketArn#region}.{dyn partitionResult#dnsSuffix}" -// while typechecking the template `"https://{dyn bucketArn#resourceId[1]}-{dyn bucketArn#accountId}.{dyn bucketArn#region}.{dyn partitionResult#dnsSuffix}"` +// while typechecking "https://{bucketArn#resourceId[1]}-{bucketArn#accountId}.{bucketArn#region}.{partitionResult#dnsSuffix}" +// while typechecking the template `"https://{bucketArn#resourceId[1]}-{bucketArn#accountId}.{bucketArn#region}.{partitionResult#dnsSuffix}"` // at invalid-rules/only-refs-coerce-isset.json5:87 // Expected string but found Option. hint: use `assign` in a condition or `isSet` to prove that this value is non-null { diff --git a/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/string-equals-unset.json5 b/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/string-equals-unset.json5 index d1063ac39b4..eb701061bc3 100644 --- a/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/string-equals-unset.json5 +++ b/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/string-equals-unset.json5 @@ -1,9 +1,7 @@ // while typechecking stringEquals("local", Region) -// at invalid-rules/string-equals-unset.json5:19 -// while typechecking stringEquals("local", Region) -// while typechecking stringEquals -// at invalid-rules/string-equals-unset.json5:24 -// Expected string but found Option. hint: use `assign` in a condition or `isSet` to prove that this value is non-null +// at invalid-rules/string-equals-unset.json5:17 +// Unexpected type in the second argument: Expected String but found Option +// hint: use `assign` in a condition or `isSet(Region)` to prove that this value is non-null { "version": "1.2", "parameters": { diff --git a/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/unknown-field.json5 b/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/unknown-field.json5 index 686a276cc5b..beb258f4757 100644 --- a/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/unknown-field.json5 +++ b/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/unknown-field.json5 @@ -3,11 +3,11 @@ // while typechecking the endpoint // at invalid-rules/unknown-field.json5:34 // while checking the URL -// while typechecking "{dyn partitionResult#nme}.amazonaws.com" -// while typechecking the template `"{dyn partitionResult#nme}.amazonaws.com"` +// while typechecking "{partitionResult#nme}.amazonaws.com" +// while typechecking the template `"{partitionResult#nme}.amazonaws.com"` // at invalid-rules/unknown-field.json5:35 -// while checking {dyn partitionResult#nme} -// while typechecking partitionResult.nme +// while checking {partitionResult#nme} +// while typechecking partitionResult#nme // {name=String, dnsSuffix=String, dualStackDnsSuffix=String, supportsDualStack=Bool, supportsFIPS=Bool} does not contain field nme { "version": "1.2", diff --git a/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/unset-in-wrong-tree.json5 b/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/unset-in-wrong-tree.json5 index 4bb9700335e..6b47e321882 100644 --- a/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/unset-in-wrong-tree.json5 +++ b/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/invalid-rules/unset-in-wrong-tree.json5 @@ -3,8 +3,8 @@ // while typechecking the endpoint // at invalid-rules/unset-in-wrong-tree.json5:37 // while checking the URL -// while typechecking "{dyn region}.amazonaws.com" -// while typechecking the template `"{dyn region}.amazonaws.com"` +// while typechecking "{region}.amazonaws.com" +// while typechecking the template `"{region}.amazonaws.com"` // at invalid-rules/unset-in-wrong-tree.json5:38 // Expected string but found Option. hint: use `assign` in a condition or `isSet` to prove that this value is non-null {