1 package net.sourceforge.pmd.lang.vm.ast;
2
3 import org.apache.commons.lang3.text.StrBuilder;
4
5 /*
6 * Licensed to the Apache Software Foundation (ASF) under one
7 * or more contributor license agreements. See the NOTICE file
8 * distributed with this work for additional information
9 * regarding copyright ownership. The ASF licenses this file
10 * to you under the Apache License, Version 2.0 (the
11 * "License"); you may not use this file except in compliance
12 * with the License. You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing,
17 * software distributed under the License is distributed on an
18 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19 * KIND, either express or implied. See the License for the
20 * specific language governing permissions and limitations
21 * under the License.
22 */
23
24
25 /**
26 * Utilities for dealing with the AST node structure.
27 *
28 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
29 * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
30 * @version $Id: NodeUtils.java 687386 2008-08-20 16:57:07Z nbubna $
31 */
32 public class NodeUtils {
33
34 /**
35 * Collect all the <SPECIAL_TOKEN>s that are carried along with a token. Special tokens do not participate in
36 * parsing but can still trigger certain lexical actions. In some cases you may want to retrieve these special
37 * tokens, this is simply a way to extract them.
38 *
39 * @param t the Token
40 * @return StrBuilder with the special tokens.
41 */
42 private static StrBuilder getSpecialText(final Token t) {
43 final StrBuilder sb = new StrBuilder();
44
45 Token tmp_t = t.specialToken;
46
47 while (tmp_t.specialToken != null) {
48 tmp_t = tmp_t.specialToken;
49 }
50
51 while (tmp_t != null) {
52 final String st = tmp_t.image;
53
54 for (int i = 0, is = st.length(); i < is; i++) {
55 final char c = st.charAt(i);
56
57 if (c == '#' || c == '$') {
58 sb.append(c);
59 }
60
61 /*
62 * more dreaded MORE hack :)
63 *
64 * looking for ("\\")*"$" sequences
65 */
66
67 if (c == '\\') {
68 boolean ok = true;
69 boolean term = false;
70
71 int j = i;
72 for (ok = true; ok && j < is; j++) {
73 final char cc = st.charAt(j);
74
75 if (cc == '\\') {
76 /*
77 * if we see a \, keep going
78 */
79 continue;
80 }
81 else if (cc == '$') {
82 /*
83 * a $ ends it correctly
84 */
85 term = true;
86 ok = false;
87 }
88 else {
89 /*
90 * nah...
91 */
92 ok = false;
93 }
94 }
95
96 if (term) {
97 final String foo = st.substring(i, j);
98 sb.append(foo);
99 i = j;
100 }
101 }
102 }
103
104 tmp_t = tmp_t.next;
105 }
106 return sb;
107 }
108
109 /**
110 * complete node literal
111 *
112 * @param t
113 * @return A node literal.
114 */
115 public static String tokenLiteral(final Token t) {
116 // Look at kind of token and return "" when it's a multiline comment
117 if (t.kind == VmParserConstants.MULTI_LINE_COMMENT) {
118 return "";
119 }
120 else if (t.specialToken == null || t.specialToken.image.startsWith("##")) {
121 return t.image;
122 }
123 else {
124 final StrBuilder special = getSpecialText(t);
125 if (special.length() > 0) {
126 return special.append(t.image).toString();
127 }
128 return t.image;
129 }
130 }
131
132 }