示例#1
0
 public override object VisitConcat(BoundConcatEx x)
 {
     return(x.Update(VisitImmutableArray(x.ArgumentsInSourceOrder)));
 }
示例#2
0
        public override object VisitConcat(BoundConcatEx x)
        {
            // transform arguments first:
            x = (BoundConcatEx)base.VisitConcat(x);

            //
            var args = x.ArgumentsInSourceOrder;

            if (args.Length == 0 || args.All(IsEmptyString))
            {
                // empty string:
                TransformationCount++;
                return(new BoundLiteral(string.Empty)
                {
                    ConstantValue = new Optional <object>(string.Empty)
                }.WithContext(x));
            }

            // visit & concat in compile time if we can:
            var newargs = args;
            int i       = 0;

            do
            {
                // accumulate evaluated string value if possible:
                if (newargs[i].Value.ConstantValue.TryConvertToString(out var value))
                {
                    string result = value;
                    int    end    = i + 1;
                    while (end < newargs.Length && newargs[end].Value.ConstantValue.TryConvertToString(out var tmp))
                    {
                        result += tmp;
                        end++;
                    }

                    if (end > i + 1) // we concat'ed something!
                    {
                        newargs = newargs.RemoveRange(i, end - i);

                        if (!string.IsNullOrEmpty(result))
                        {
                            newargs = newargs.Insert(i, BoundArgument.Create(new BoundLiteral(result)
                            {
                                ConstantValue = new Optional <object>(result),
                                TypeRefMask   = _routine.TypeRefContext.GetStringTypeMask(),
                                ResultType    = DeclaringCompilation.CoreTypes.String,
                            }.WithAccess(BoundAccess.Read)));
                        }
                    }
                }

                //
                i++;
            } while (i < newargs.Length);

            //
            if (newargs != args)
            {
                TransformationCount++;

                if (newargs.Length == 0)
                {
                    return(new BoundLiteral(string.Empty)
                    {
                        ConstantValue = new Optional <object>(string.Empty)
                    }.WithContext(x));
                }
                else if (newargs.Length == 1 && newargs[0].Value.ConstantValue.TryConvertToString(out var value))
                {
                    // "value"
                    return(new BoundLiteral(value)
                    {
                        ConstantValue = new Optional <object>(value)
                    }.WithContext(x));
                }

                //
                return(x.Update(newargs));
            }

            //
            return(x);
        }