JavaParser Source Viewer

Home|JavaParser/com/github/javaparser/ast/expr/TextBlockLiteralExpr.java
1/*
2 * Copyright (C) 2007-2010 JĂșlio Vilmar Gesser.
3 * Copyright (C) 2011, 2013-2020 The JavaParser Team.
4 *
5 * This file is part of JavaParser.
6 *
7 * JavaParser can be used either under the terms of
8 * a) the GNU Lesser General Public License as published by
9 *     the Free Software Foundation, either version 3 of the License, or
10 *     (at your option) any later version.
11 * b) the terms of the Apache License
12 *
13 * You should have received a copy of both licenses in LICENCE.LGPL and
14 * LICENCE.APACHE. Please refer to those files for details.
15 *
16 * JavaParser is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 * GNU Lesser General Public License for more details.
20 */
21package com.github.javaparser.ast.expr;
22
23import com.github.javaparser.TokenRange;
24import com.github.javaparser.ast.AllFieldsConstructor;
25import com.github.javaparser.ast.Generated;
26import com.github.javaparser.ast.Node;
27import com.github.javaparser.ast.visitor.CloneVisitor;
28import com.github.javaparser.ast.visitor.GenericVisitor;
29import com.github.javaparser.ast.visitor.VoidVisitor;
30import com.github.javaparser.metamodel.JavaParserMetaModel;
31import com.github.javaparser.metamodel.TextBlockLiteralExprMetaModel;
32import com.github.javaparser.utils.Pair;
33import java.util.Arrays;
34import java.util.Optional;
35import java.util.function.Consumer;
36import java.util.stream.Stream;
37import static com.github.javaparser.utils.StringEscapeUtils.unescapeJavaTextBlock;
38import static java.util.stream.Collectors.joining;
39import static java.util.stream.IntStream.range;
40
41/**
42 * <h1>A text block</h1>
43 * <h2>Java 13-</h2>
44 * A text block is a multi-line string. It was introduced in JEP 355.
45 * The content of "value" is byte-for-byte exactly what is in the source code.
46 */
47public class TextBlockLiteralExpr extends LiteralStringValueExpr {
48
49    public TextBlockLiteralExpr() {
50        this(null"empty");
51    }
52
53    /**
54     * Creates a text block literal expression from given string.
55     *
56     * @param value the value of the literal
57     */
58    @AllFieldsConstructor
59    public TextBlockLiteralExpr(final String value) {
60        this(nullvalue);
61    }
62
63    /**
64     * This constructor is used by the parser and is considered private.
65     */
66    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
67    public TextBlockLiteralExpr(TokenRange tokenRangeString value) {
68        super(tokenRangevalue);
69        customInitialization();
70    }
71
72    @Override
73    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
74    public <RAR accept(final GenericVisitor<RAvfinal A arg) {
75        return v.visit(this, arg);
76    }
77
78    @Override
79    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
80    public <Avoid accept(final VoidVisitor<Avfinal A arg) {
81        v.visit(this, arg);
82    }
83
84    @Override
85    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
86    public boolean remove(Node node) {
87        if (node == null)
88            return false;
89        return super.remove(node);
90    }
91
92    @Override
93    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
94    public boolean isTextBlockLiteralExpr() {
95        return true;
96    }
97
98    @Override
99    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
100    public TextBlockLiteralExpr asTextBlockLiteralExpr() {
101        return this;
102    }
103
104    @Override
105    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
106    public Optional<TextBlockLiteralExprtoTextBlockLiteralExpr() {
107        return Optional.of(this);
108    }
109
110    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
111    public void ifTextBlockLiteralExpr(Consumer<TextBlockLiteralExpraction) {
112        action.accept(this);
113    }
114
115    @Override
116    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
117    public boolean replace(Node nodeNode replacementNode) {
118        if (node == null)
119            return false;
120        return super.replace(nodereplacementNode);
121    }
122
123    @Override
124    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
125    public TextBlockLiteralExpr clone() {
126        return (TextBlockLiteralExpraccept(new CloneVisitor(), null);
127    }
128
129    @Override
130    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
131    public TextBlockLiteralExprMetaModel getMetaModel() {
132        return JavaParserMetaModel.textBlockLiteralExprMetaModel;
133    }
134
135    /**
136     * Most of the algorithm for stripIndent, stopping just before concatenating all the lines into a single string.
137     * Useful for tools.
138     */
139    public Stream<StringstripIndentOfLines() {
140        /* Split the content of the text block at every LF, producing a list of individual lines. 
141        Note that any line in the content which was just an LF will become an empty line in the list of individual lines. */
142        String[] rawLines = getValue().split("\\R", -1);
143        /* Add all non-blank lines from the list of individual lines into a set of determining lines. 
144        (Blank lines -- lines that are empty or are composed wholly of white space -- have no visible influence on the indentation. 
145        Excluding blank lines from the set of determining lines avoids throwing off step 4 of the algorithm.) */
146        /* If the last line in the list of individual lines (i.e., the line with the closing delimiter) is blank, then add it to the set of determining lines. 
147        (The indentation of the closing delimiter should influence the indentation of the content as a whole -- a "significant trailing line" policy.) */
148        /* Compute the common white space prefix of the set of determining lines, by counting the number of leading white space characters on each line and taking the minimum count. */
149        int commonWhiteSpacePrefixSize = range(0rawLines.length).mapToObj(nr -> new Pair<>(nrrawLines[nr])).filter(l -> !emptyOrWhitespace(l.b) || isLastLine(rawLinesl.a)).map(l -> indentSize(l.b)).min(Integer::compare).orElse(0);
150        /* Remove the common white space prefix from each non-blank line in the list of individual lines. */
151        /* Remove all trailing white space from all lines in the modified list of individual lines from step 5. 
152        This step collapses wholly-whitespace lines in the modified list so that they are empty, but does not discard them. */
153        return Arrays.stream(rawLines).map(l -> l.substring(commonWhiteSpacePrefixSize)).map(this::trimTrailing);
154    }
155
156    /**
157     * @return The algorithm from String::stripIndent in JDK 13.
158     */
159    public String stripIndent() {
160        /* Construct the result string by joining all the lines in the modified list of individual lines from step 6, using LF as the separator between lines. 
161        If the final line in the list from step 6 is empty, then the joining LF from the previous line will be the last character in the result string. */
162        return stripIndentOfLines().collect(joining("\n"));
163    }
164
165    /**
166     * @return The algorithm from String::translateEscapes in JDK 13.
167     */
168    public String translateEscapes() {
169        return unescapeJavaTextBlock(stripIndent());
170    }
171
172    /**
173     * @return the final string value of this text block after all processing.
174     */
175    public String asString() {
176        return translateEscapes();
177    }
178
179    /**
180     * @return is the line with index lineNr the last line in rawLines?
181     */
182    private boolean isLastLine(String[] rawLinesInteger lineNr) {
183        return lineNr == rawLines.length - 1;
184    }
185
186    /**
187     * @return is this string empty or filled only with whitespace?
188     */
189    private boolean emptyOrWhitespace(String rawLine) {
190        return rawLine.trim().isEmpty();
191    }
192
193    /**
194     * @return the amount of leading whitespaces.
195     */
196    private int indentSize(String s) {
197        String content = s.trim();
198        if (content.isEmpty()) {
199            return s.length();
200        }
201        return s.indexOf(content);
202    }
203
204    /**
205     * Can be replaced when moving to JDK 11
206     */
207    private String trimTrailing(String source) {
208        int pos = source.length() - 1;
209        while ((pos >= 0) && Character.isWhitespace(source.charAt(pos))) {
210            pos--;
211        }
212        pos++;
213        return (pos < source.length()) ? source.substring(0pos) : source;
214    }
215}
216
MembersX
TextBlockLiteralExpr:asTextBlockLiteralExpr
TextBlockLiteralExpr:toTextBlockLiteralExpr
TextBlockLiteralExpr:ifTextBlockLiteralExpr
TextBlockLiteralExpr:stripIndentOfLines
TextBlockLiteralExpr:clone
TextBlockLiteralExpr:stripIndentOfLines:Block:rawLines
TextBlockLiteralExpr:replace
TextBlockLiteralExpr:translateEscapes
TextBlockLiteralExpr:trimTrailing:Block:pos
TextBlockLiteralExpr:indentSize
TextBlockLiteralExpr:remove
TextBlockLiteralExpr:isTextBlockLiteralExpr
TextBlockLiteralExpr:accept
TextBlockLiteralExpr:emptyOrWhitespace
TextBlockLiteralExpr:stripIndentOfLines:Block:commonWhiteSpacePrefixSize
TextBlockLiteralExpr:getMetaModel
TextBlockLiteralExpr:trimTrailing
TextBlockLiteralExpr:TextBlockLiteralExpr
TextBlockLiteralExpr:asString
TextBlockLiteralExpr:stripIndent
TextBlockLiteralExpr:indentSize:Block:content
TextBlockLiteralExpr:isLastLine
Members
X