Beispiel #1
0
        public virtual LangElement HeredocExpression(Span span, LangElement expression, Tokens quoteStyle, Lexer.HereDocTokenValue heredoc)
        {
            Debug.Assert(heredoc != null);

            switch (quoteStyle)
            {
            case Tokens.T_SINGLE_QUOTES:
                return(new NowDocExpression(span, (Expression)expression, heredoc.Label));

            default:
                return(new HereDocExpression(span, (Expression)expression, heredoc.Label, quoteStyle == Tokens.T_DOUBLE_QUOTES));
            }
        }
Beispiel #2
0
        /// <summary>
        /// Traverse through the expression (either <see cref="IStringLiteralValue"/> or concat of <see cref="IStringLiteralValue"/>s),
        /// and checks and removes the leading whitespace indentation.
        /// </summary>
        /// <param name="element">Either <see cref="IStringLiteralValue"/> or <see cref="IConcatEx"/> with <see cref="IStringLiteralValue"/>s.</param>
        /// <param name="heredoc">Heredoc information.</param>
        /// <param name="lineBegin">Whether the element starts at line beginning.</param>
        LangElement RemoveHereDocIndentation(LangElement element, Lexer.HereDocTokenValue heredoc, bool lineBegin)
        {
            var indentation = heredoc.Indentation.AsSpan();

            if (indentation.IsEmpty)
            {
                return element;
            }

            if (!indentation.IsWhiteSpace())
            {
                throw new ArgumentException("", nameof(indentation));
            }

            //
            if (element is ConcatEx concat)
            {
                var parts = concat.Expressions;
                for (int i = 0; i < parts.Length; i++)
                {
                    parts[i] = (Expression)RemoveHereDocIndentation(parts[i], heredoc, lineBegin && i == 0);
                }
            }
            else if (element is IStringLiteralValue str) // i.e. StringLiteral
            {
                // if (str.Contains8bitText) // TODO, use str.EnumerateChunks() : byte[]|string

                var content = str.ToString();

                var result = StringUtils.GetStringBuilder(content.Length);
                var errorreported = false;

                foreach (var lineSpan in TextUtils.EnumerateLines(content, true))
                {
                    if (lineBegin)
                    {
                        var lineText = content.AsSpan(lineSpan.Start, lineSpan.Length);
                        if (lineText.StartsWith(indentation))
                        {
                            result.Append(content, lineSpan.Start + indentation.Length, lineSpan.Length - indentation.Length);
                            continue;
                        }
                        else if (lineText.IsWhiteSpace())
                        {
                            // allowed, empty line
                            // add the line break
                            result.Append(lineText.TrimStart(" \t".AsSpan()).ToString());
                            continue;
                        }
                        else if (!errorreported)
                        {
                            // error
                            _errors.Error(element.Span, FatalErrors.HeredocIndentError);
                            errorreported = true; // report error just once
                        }
                    }

                    // next lines are from the line begin
                    lineBegin = true;
                    result.Append(content, lineSpan.Start, lineSpan.Length);
                }

                return new StringLiteral(element.Span, StringUtils.ReturnStringBuilder(result));
            }

            return element;
        }
Beispiel #3
0
 public override LangElement HeredocExpression(Span span, LangElement expression, Tokens quoteStyle, Lexer.HereDocTokenValue heredoc)
 => CountLE(base.HeredocExpression(span, expression, quoteStyle, heredoc));