示例#1
0
        public void EmitCopyObject(string?name, ForSyntax syntax, SyntaxBase?input, string?copyIndexOverride = null)
        {
            writer.WriteStartObject();

            if (name is not null)
            {
                this.EmitProperty("name", name);
            }

            // construct the length ARM expression from the Bicep array expression
            // type check has already ensured that the array expression is an array
            this.EmitPropertyWithTransform(
                "count",
                syntax.Expression,
                arrayExpression => new FunctionExpression("length", new[] { arrayExpression }, Array.Empty <LanguageExpression>()));

            if (input != null)
            {
                if (copyIndexOverride == null)
                {
                    this.EmitProperty("input", input);
                }
                else
                {
                    this.EmitPropertyWithTransform("input", input, expression =>
                    {
                        // the named copy index in the serialized expression is incorrect
                        // because the object syntax here does not match the JSON equivalent due to the presence of { "value": ... } wrappers
                        // for now, we will manually replace the copy index in the converted expression
                        // this approach will not work for nested property loops
                        var visitor = new LanguageExpressionVisitor
                        {
                            OnFunctionExpression = function =>
                            {
                                if (string.Equals(function.Function, "copyIndex") &&
                                    function.Parameters.Length == 1 &&
                                    function.Parameters[0] is JTokenExpression)
                                {
                                    // it's an invocation of the copyIndex function with 1 argument with a literal value
                                    // replace the argument with the correct value
                                    function.Parameters = new LanguageExpression[] { new JTokenExpression("value") };
                                }
                            }
                        };

                        // mutate the expression
                        expression.Accept(visitor);

                        return(expression);
                    });
                }
            }

            writer.WriteEndObject();
        }
示例#2
0
        public static void VisitExpressions <TToken>(TToken input, Action <LanguageExpression> visitFunc)
            where TToken : JToken
        {
            var visitor = new LanguageExpressionVisitor
            {
                OnFunctionExpression = visitFunc,
                OnJTokenExpression   = visitFunc,
            };

            void VisitLanguageExpressions(string value)
            {
                if (ExpressionsEngine.IsLanguageExpression(value))
                {
                    var expression = ExpressionsEngine.ParseLanguageExpression(value);
                    expression.Accept(visitor);
                }
            }

            if (input is JValue jValue && jValue.ToObject <string>() is { } value)
            {
                VisitLanguageExpressions(value);
                return;
            }

            JsonUtility.WalkJsonRecursive(
                input,
                objectAction: @object =>
            {
                foreach (var property in @object.Properties())
                {
                    VisitLanguageExpressions(property.Name);
                }
            },
                tokenAction: token =>
            {
                if (token.Type == JTokenType.String && token.ToObject <string>() is { } value)
                {
                    VisitLanguageExpressions(value);
                }
            });